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 :

Screenshot_2015-03-31-17-13-26

 


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.

durga chiranjeevi

durga chiranjeevi

I'm currently working as Android developer at Energy Alternatives India. Interested in Application and Game development.
durga chiranjeevi
Comments
  1. Narsi
  2. Igor Ganapolsky
  3. John

Leave a Reply

Your email address will not be published. Required fields are marked *