Awesome custom ratingbar
And how do we get there? First, we’ll need a
styles.xml
file, which describes our custom styles and lives in the values
folder:
1
2
3
4
5
6
7
8
| <? xml version = "1.0" encoding = "utf-8" ?> < resources > < style name = "foodRatingBar" parent = "@android:style/Widget.RatingBar" > < item name = "android:progressDrawable" >@drawable/food_ratingbar_full</ item > < item name = "android:minHeight" >48dip</ item > < item name = "android:maxHeight" >48dip</ item > </ style > </ resources > |
This creates a new custom style called
foodRatingBar
which extends Widget.RatingBar
style, sets its height to 48 pixels and its progressDrawable
to food_rating_bar
(RatingBar
is just an extension of a ProgressBar
, and each “star” in the RatingBar
is basically just another “tick” — progressDrawable
— in the ProgressBar
). progressDrawable
documentation is rather lacking, and the only way I figured out which element I needed to style was by looking through Android’s source code (which is a great way to learn things, by the way). It also provides an insight on what should go into the food_rating_bar_full Drawable
:
1
2
3
4
5
6
7
8
9
| <? xml version = "1.0" encoding = "utf-8" ?> < item android:id = "@+android:id/background" android:drawable = "@drawable/food_ratingbar_full_empty" /> < item android:id = "@+android:id/secondaryProgress" android:drawable = "@drawable/food_ratingbar_full_empty" /> < item android:id = "@+android:id/progress" android:drawable = "@drawable/food_ratingbar_full_filled" /> </ layer-list > |
Basically, it lists out different
Drawable
s to use for background (no cookie — food_ratingbar_full_empty
) and progress (selected cookie —food_ratingbar_full_filled
). These Drawable
s are selectors which list out the images to be used in different RatingBar
selection states. Here’s an example of a filled rating (cookie):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| <? xml version = "1.0" encoding = "utf-8" ?> <!-- This is the rating bar drawable that is used to show a filled cookie. --> < selector < item android:state_pressed = "true" android:state_window_focused = "true" android:drawable = "@drawable/cookie" /> < item android:state_focused = "true" android:state_window_focused = "true" android:drawable = "@drawable/cookie" /> < item android:state_selected = "true" android:state_window_focused = "true" android:drawable = "@drawable/cookie" /> < item android:drawable = "@drawable/cookie" /> </ selector > |
I just use one image for all states (and it actually looks decent), but as you can see from the selector, there are four different states possible (
@drawable/cookie
is finally an actuall cookie png image). And the cool thing here is that RatingBar
component will automatically fill in part of the cookie when needed based only on “full” and “empty” images (if you support half ratings, as in my example image).
Finally, it’s time to apply the style to the
RatingBar
, which is the easiest part — we just add a style attribute to the <RatingBar>
:
1
2
3
| < RatingBar android:id = "@+id/my_rating_bar" ... style = "@style/foodRatingBar" /> |
And that’s it,
RatingBar
transformation is complete!
One last thing to note is that there are three different types of
RatingBar
— one interactive, and two read-only (small and large). In order to style the read-only ones, you would need to create another custom style that extends from the appropriate read-only style — for example, for a small one, it would look like this:
1
2
3
4
5
| < style name = "foodRatingBarSmall" parent = "@android:style/Widget.RatingBar.Small" > < item name = "android:progressDrawable" >@drawable/food_ratingbar_small</ item > < item name = "android:minHeight" >16dip</ item > < item name = "android:maxHeight" >16dip</ item > </ style > |
Basically, we’re just extending from a different parent style, and providing different (smaller) images, and in the read-only case, the half “star” image also needs to be provided.
Have Fun!
No comments: