By this post, I would like to present a sample project about this RatingBar matter, hope that can be useful for caching the RatingBar status when integrating in ListView. See this DEMO VIDEO first:
Customizing a ListView adapter
Set max stars for Rating bar though android:numStars property and set rating step by android:stepSize.
In adapter code, we should override the getView() method and inflate this xml layout with every ListView item!
The most important step is handling the RatingBar event invoking by user, we will update item ListView value (rating stars) by it. So, provide this OnRatingBarChangeListener method:
private RatingBar.OnRatingBarChangeListener onRatingChangedListener(final ViewHolder holder, final int position) { return new RatingBar.OnRatingBarChangeListener() { @Override public void onRatingChanged(RatingBar ratingBar, float v, boolean b) { Movie item = getItem(position); item.setRatingStar(v); } }; }In getView(), using it by set this code to RatingBar:
holder.ratingBar.setOnRatingBarChangeListener(onRatingChangedListener(holder, position));And now we have full adapter code:
package info.devexchanges.ratingbarlistview; import android.app.Activity; import android.content.Context; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.LinearLayout; import android.widget.RatingBar; import android.widget.TextView; import java.util.List; public class ListViewAdapter extends ArrayAdapter<Movie> { private AppCompatActivity activity; private List<Movie> movieList; public ListViewAdapter(AppCompatActivity context, int resource, List<Movie> objects) { super(context, resource, objects); this.activity = context; this.movieList = objects; } @Override public Movie getItem(int position) { return movieList.get(position); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); if (convertView == null) { convertView = inflater.inflate(R.layout.item_listview, parent, false); holder = new ViewHolder(convertView); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); //holder.ratingBar.getTag(position); } holder.ratingBar.setOnRatingBarChangeListener(onRatingChangedListener(holder, position)); holder.ratingBar.setTag(position); holder.ratingBar.setRating(getItem(position).getRatingStar()); holder.movieName.setText(getItem(position).getName()); return convertView; } private RatingBar.OnRatingBarChangeListener onRatingChangedListener(final ViewHolder holder, final int position) { return new RatingBar.OnRatingBarChangeListener() { @Override public void onRatingChanged(RatingBar ratingBar, float v, boolean b) { Movie item = getItem(position); item.setRatingStar(v); Log.i("Adapter", "star: " + v); } }; } private static class ViewHolder { private RatingBar ratingBar; private TextView movieName; public ViewHolder(View view) { ratingBar = (RatingBar) view.findViewById(R.id.rate_img); movieName = (TextView) view.findViewById(R.id.text); } } }
Activity coding
package info.devexchanges.ratingbarlistview; import android.annotation.SuppressLint; import android.app.Dialog; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { private ListView listView; private ArrayAdapter<Movie> adapter; private ArrayList<Movie> arrayList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (ListView)findViewById(R.id.list_view); setLisData(); adapter = new ListViewAdapter(this, R.layout.item_listview, arrayList); listView.setAdapter(adapter); listView.setOnItemClickListener(onItemClickListener()); } private AdapterView.OnItemClickListener onItemClickListener() { return new AdapterView.OnItemClickListener() { @SuppressLint("SetTextI18n") @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { final Dialog dialog = new Dialog(MainActivity.this); dialog.setContentView(R.layout.layout_dialog); dialog.setTitle("Movie details"); TextView name = (TextView) dialog.findViewById(R.id.movie_name); TextView country = (TextView) dialog.findViewById(R.id.country); TextView starRate = (TextView) dialog.findViewById(R.id.rate); Movie movie = (Movie) parent.getAdapter().getItem(position); name.setText("Movie name: " + movie.getName()); country.setText("Producing country: " + movie.getCountry()); starRate.setText("Your rate: " + movie.getRatingStar()); dialog.show(); } }; } private void setLisData() { arrayList = new ArrayList<>(); arrayList.add(new Movie(1, "Avenger 2: Age of Ultron", "USA")); arrayList.add(new Movie(1, "Ant man", "USA")); arrayList.add(new Movie(1, "Ted 2", "USA")); arrayList.add(new Movie(1, "Cities In Love", "China")); arrayList.add(new Movie(1, "Attack on Titan 2: End of the World", "Japan")); arrayList.add(new Movie(1, "Dragon Ball Z: The Fall of Men", "France")); arrayList.add(new Movie(1, "Hitman: Agent 47", "USA")); arrayList.add(new Movie(1, "Criminal Activities", "USA")); arrayList.add(new Movie(1, "The Witness", "China")); arrayList.add(new Movie(1, "Paris Holiday ", "HongKong")); arrayList.add(new Movie(1, "The Beauty Inside", "Korea")); arrayList.add(new Movie(1, "Phantom", "USA")); arrayList.add(new Movie(1, "Youth", "France")); arrayList.add(new Movie(1, "The Third Way Of Love", "China")); arrayList.add(new Movie(1, "Maze Runner 2: The Scorch Trials", "USA")); } }
Styling RatingBar
Ofcourse, also putting the selector drawables for it (by create new drawable resource in res/drawable folder):
Declaring to use this style for RatingBar in main activity layout:
And output will be like it:
The model (POJO) of this project:
package info.devexchanges.ratingbarlistview; public class Movie { private float ratingStar; private String name; private String country; public Movie(int ratingStar, String name, String country) { this.ratingStar = ratingStar; this.name = name; this.country = country; } public float getRatingStar() { return ratingStar; } public void setRatingStar(float ratingStar) { this.ratingStar = ratingStar; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } }