Search code examples
androidandroid-cursoradapterratingbar

Rating Bar inside ListView mixes list items


I have been trying to implement a ListView, which has Rating Bar inside. I have onRatingChanged listener and I want to change a TextView inside the item depending on the rating.

The problem is that, when I touch stars and update it, it updates another TextView's value. My Adapter extends CursorAdapter. If I had getView() I guess I would solve it but I dont know how to deal with CursorAdapter since we are not using getView().

|------------------|
| TextView         | ---> TextView I want to update
| * * * * *        | ---> Rating Bar
|                  |
|__________________|

Solution

  • The problem is that, when I touch stars and update it, it updates another TextView's value. My Adapter extends CursorAdapter. If I had getView() I guess I would solve it but I dont know how to deal with CursorAdapter since we are not using getView().

    Like I already said in my comment in the case of Cursor based adapter you would use the newView() and bindView() methods. Below is a small example:

    public class CustomAdapter extends CursorAdapter {
    
        private static final int CURSOR_TEXT_COLUMN = 0;
    
        public CustomAdapter(Context context, Cursor c, int flags) {
            super(context, c, flags);
    
        }
    
        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            ViewHolder holder = (ViewHolder) view.getTag();
            holder.text.setText(cursor.getString(CURSOR_TEXT_COLUMN));
            holder.progress
                    .setOnRatingBarChangeListener(new OnRatingBarChangeListener() {
    
                        @Override
                        public void onRatingChanged(RatingBar ratingBar,
                                float rating, boolean fromUser) {
                            // basic example on how you may update the
                            // TextView(you could use a tag etc).
                            // Keep in mind that if you scroll this row and come
                            // back the value will reset as you need to save the
                            // new rating in a more persistent way and update
                            // the progress
                            View rowView = (View) ratingBar.getParent();
                            TextView text = (TextView) rowView
                                    .findViewById(R.id.the_text);
                            text.setText(String.valueOf(rating));
                        }
                    });
        }
    
        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            LayoutInflater mInflater = LayoutInflater.from(context);
            View rowView = mInflater.inflate(R.layout.row_layout, parent,
                    false);
            ViewHolder holder = new ViewHolder();
            holder.text = (TextView) rowView.findViewById(R.id.the_text);
            holder.progress = (RatingBar) rowView
                    .findViewById(R.id.the_progress);
            rowView.setTag(holder);
            return rowView;
        }
    
        static class ViewHolder {
            TextView text;
            RatingBar progress;
        }
    
    }