How to code Custom RatingBar in Android
In this blog post, I’ll explain how to code RatingBar in Android with different styles and how to customizing.
Step 1: Create a new project File -> Android Project. While creating a new project give activity name as MainActivity.
Step 2: Open your activity_main.xml and copy paste this code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.skholingua.android.custom_ratingbar.MainActivity" > <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/ratingBar1" android:layout_centerHorizontal="true" android:text="Default - Indicator" android:textAppearance="?android:attr/textAppearanceSmall" /> <TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_below="@+id/ratingBar2" android:layout_marginTop="15dp" android:text="Default - Small" android:textAppearance="?android:attr/textAppearanceSmall" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/ratingBar3" android:layout_centerHorizontal="true" android:layout_marginTop="32dp" android:text="Custom - Only Color" android:textAppearance="?android:attr/textAppearanceSmall" /> <RatingBar android:id="@+id/ratingBar5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_below="@+id/textView2" /> <RatingBar android:id="@+id/ratingBar2" style="?android:attr/ratingBarStyleIndicator" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView3" android:layout_centerHorizontal="true" /> <RatingBar android:id="@+id/ratingBar1" style="?android:attr/ratingBarStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_below="@+id/textView1" /> <RatingBar android:id="@+id/ratingBar3" style="?android:attr/ratingBarStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_below="@+id/textView4" /> <RatingBar android:id="@+id/ratingBar4" style="@style/StarRatingBar" android:layout_width="wrap_content" android:layout_height="50dp" android:layout_centerHorizontal="true" android:layout_below="@+id/textView5" /> <TextView android:id="@+id/textView6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/ratingBar4" android:layout_centerHorizontal="true" android:text="RatingBar with only one touch" android:textAppearance="?android:attr/textAppearanceSmall" /> <RatingBar android:id="@+id/ratingBar6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_below="@+id/textView6" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="29dp" android:text="Default Style" android:textAppearance="?android:attr/textAppearanceSmall" /> <TextView android:id="@+id/textView5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/ratingBar5" android:layout_centerHorizontal="true" android:text="Custom - Images" android:textAppearance="?android:attr/textAppearanceSmall" /> </RelativeLayout>
Step 3: Open MainActivity class and copy paste this code:
package com.skholingua.android.custom_ratingbar; import android.app.Activity; import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.drawable.LayerDrawable; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.widget.RatingBar; import android.widget.RatingBar.OnRatingBarChangeListener; public class MainActivity extends Activity { private RatingBar rb_customColor, rb_Default, rb_oneTouch, rb_Indicator, rb_small; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); rb_customColor = (RatingBar) findViewById(R.id.ratingBar5); rb_Default = (RatingBar) findViewById(R.id.ratingBar1); rb_Indicator = (RatingBar) findViewById(R.id.ratingBar2); rb_small = (RatingBar) findViewById(R.id.ratingBar3); rb_oneTouch = (RatingBar) findViewById(R.id.ratingBar6); /* * For custom color only using layerdrawable to fill the star colors */ LayerDrawable stars = (LayerDrawable) rb_customColor .getProgressDrawable(); stars.getDrawable(2).setColorFilter(Color.parseColor("#26ce61"), PorterDuff.Mode.SRC_ATOP); // for filled stars stars.getDrawable(1).setColorFilter(Color.parseColor("#FFFF00"), PorterDuff.Mode.SRC_ATOP); // for half filled stars stars.getDrawable(0).setColorFilter(Color.CYAN, PorterDuff.Mode.SRC_ATOP); // for empty stars /* * For One Touch RatingBar, here after touching the rating bar it's * IsIndicator will cahnged to ture and make no more touch on it */ rb_oneTouch .setOnRatingBarChangeListener(new OnRatingBarChangeListener() { @Override public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) { doRating(rating); } }); /* * DefaultStyleIndicator and DefaultStyleSmall RatingBar are only * Indicator by default, they won't have any changelistener */ rb_Default .setOnRatingBarChangeListener(new OnRatingBarChangeListener() { @Override public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) { rb_Indicator.setRating(rating); rb_small.setRating(rating); } }); } protected void doRating(float rating) { // setIsIndiacator(false) is used to allow changes/touch on the stars // rb_oneTouch.setIsIndicator(false); // using Math.celi(double) to set // the highest value to the // stars i.e if rating is // between 3 - 4 stars, then it // displays as 4 stars int _rating = (int) Math.ceil(rating); rb_oneTouch.setRating(_rating); // setIsIndiacator(true) it won't allow to changes/touch on the stars rb_oneTouch.setIsIndicator(true); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
Step 4: Open styles.xml and copy paste this code:
<style name="StarRatingBar" parent="@android:style/Widget.RatingBar"> <item name="android:progressDrawable">@drawable/ratingbar_selector</item> <item name="android:minHeight">48dip</item> <item name="android:maxHeight">48dip</item> </style>
This creates a new custom style called StarRatingBar which extends Widget.RatingBar style, sets its height to 48 pixels and its progressDrawable to ratingbar_selector.
Step 5: Create new xml file in drawable folder, ratingbar_selector.xml and copy paste this code:
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+android:id/background" android:drawable="@drawable/skholinguaicon_blue"/> <item android:id="@+android:id/secondaryProgress" android:drawable="@drawable/skholinguaicon_blue"/> <item android:id="@+android:id/progress" android:drawable="@drawable/skholinguaicon"/> </layer-list>
It lists out different Drawables to use for Background & Progress. These Drawables are selectors which list out the images to be used in different RatingBar selection states.
ScreenShot :
Tips to Remember always:
1) Default ratingBarStyle, style for the RatingBar is the only default style takes up OnRatingBarChangeListener(), where as ratingBarStyleSmall and ratingBarStyleIndicator are actually an Indicator only(i.e just to display stars).
2) To change the star colors only, i used LayerDrawables to fill the colors of the stars. LayerDrawable is a Drawable that manages an array of other Drawables. These are drawn in array order, so the element with the largest index will be drawn on top. It can be defined in an XML file with the <layer-list>
element. Each Drawable in the layer is defined in a nested <item>
.
3) To change the star images only, i used the <layer-list>
element with different images i.e, for background, secondary progress and progress with my own images.
4) ratingbar.setIsIndicator(boolean) is used to change the rating bar as an indicator (and non-changeable by the user). In XML style, use android:isIndicator=”boolean”. So, on one touch style, after user clicking on the rating bar, i’ve changed setIsIndicator to true and if the user want to change the rating, then make sure you set it false before onRatingChangeListener has been called.
5) If you want to change the Indicator style rating bar to your own style, then add this snippet to your style.xml class and add this style to the rating bar.
<style name="StarRatingBarSmall" parent="@android:style/Widget.RatingBar.Small"> <item name="android:progressDrawable">@drawable/ratingbar_selector_small</item> <item name="android:minHeight">16dip</item> <item name="android:maxHeight">16dip</item> </style>
Hope this helpful. Your valuable comments are always welcomed. It will help to improve my post and understanding.
Download Source Code from here.
Related Posts
durga chiranjeevi
Latest posts by durga chiranjeevi (see all)
- Sharing Application Data Between Two Android Apps – Part III - April 8, 2015
- Sharing Application Data Between Two Android Apps – Part II - April 8, 2015
- Sharing Application Data Between Two Android Apps – Part I - April 8, 2015
Great explanation, good job!
You are doing a wonderful service to all Android developers
Thanks for the writeup. It really helped me to create a custom RatingBar with images. However, you have a bug in your ratingbar_selector.xml. You aren’t supposed to put ‘+’ in @android.
Hi. I’m trying to implement the “rb_customColor” in my app and it crushes right after this line:
LayerDrawable stars = (LayerDrawable) rb_customColor.getProgressDrawable();
What can be the reason for that?