5

I have a RecyclerView which loads CheckBoxes on CardViews. This is the adapter. It is fine when it loads. But when I check an item on RecyclerView intentionally, a CheckBox is checked somewhere random. How can I get rid of this problem? Here is my adapter. Thanks in advance.

public class QuestionsAdapter extends RecyclerView.Adapter<QuestionsAdapter.QuestionsViewHolder> {
    List<QuestionModel> Questions;
    public Context context;

    public QuestionsAdapter(Context context, List<QuestionModel> questions) {
        this.Questions = questions;
        this.context = context;
    }

    @Override
    public QuestionsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.questions_card_view, parent, false);
        return new QuestionsViewHolder(v);
    }

    @Override
    public void onBindViewHolder(QuestionsViewHolder holder, final int position) {
        holder.txtQuestionText.setText(Questions.get(position).QuestionText);
    }

    @Override
    public int getItemCount() {
        return Questions.size();
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    public class QuestionsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public RadioButton rbLike;
        public RadioButton rbdisLike;
        public RadioButton rbnoComment;
        public TextView txtQuestionText;

        public QuestionsViewHolder(View itemView) {
            super(itemView);
            rbLike = (RadioButton) itemView.findViewById(R.id.like);
            rbdisLike = (RadioButton) itemView.findViewById(R.id.Dislike);
            txtQuestionText = (TextView) itemView.findViewById(R.id.txtCardQuestion);
            rbnoComment = (RadioButton) itemView.findViewById(R.id.NoComment);
            rbnoComment.setOnClickListener(this);
            rbdisLike.setOnClickListener(this);
            rbLike.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.like:
                    rbLike.setChecked(true);
                    rbnoComment.setChecked(false);
                    rbdisLike.setChecked(false);

                    break;
                case R.id.Dislike:
                    rbdisLike.setChecked(true);
                    rbnoComment.setChecked(false);
                    rbLike.setChecked(false);
                    break;
                case R.id.NoComment:
                    rbnoComment.setChecked(true);
                    rbLike.setChecked(false);
                    rbdisLike.setChecked(false);
                    //do something
                    break;

                default:
            }
        }
    }
}
Gonenc Turkekul
  • 285
  • 1
  • 4
  • 18
  • The only thing you need to change is the default case. You MUST add logic in default because you will have this kind of problems because the recycle of Views. – FacuArg Feb 18 '20 at 19:20

4 Answers4

5

There is a problem in your onBindViewHolder() method... RecyclerView going to reuse ViewHolders during scrolling. For that reason you should set state for all views in the ViewHolder to see consistent data. Now you set only text for "txtQuestionText". In this case you will see consistent text for the list item and random state for the RadioButtons.

In brief you should have something like this:

@Override
public void onBindViewHolder(QuestionsViewHolder holder, final int position) {
    holder.setModel(Questions.get(position));
}

...

public class QuestionsViewHolder ...
...
public void setModel(QuestionModel model){
    rbLike.setChecked(model.like);
    rbdisLike.setChecked(model.dislike);
    rbnoComment.setChecked(model.comment);
    txtQuestionText.setText(model.text);
}
lganzzzo
  • 558
  • 3
  • 10
1

in my case, i have following code like this :

if (checkpoint.getIsAttendance() == 1) { 
    holder.checkBoxAttendance.setChecked(true);
}

and its happen, the checkboxes randomly checked.

after i changed the code like below

if (checkpoint.getIsAttendance() == 1) { 
    holder.checkBoxAttendance.setChecked(true);
} else { 
    holder.checkBoxAttendance.setChecked(false);
}

random checked checkboxes dissappear.

Ben P.
  • 52,661
  • 6
  • 95
  • 123
Denny Sitorus
  • 108
  • 1
  • 5
0
if (itemChecked[position])
            holder.ck1.setChecked(true);
        else
            holder.ck1.setChecked(false);

    holder.ck1.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if (holder.ck1.isChecked())
                itemChecked[position] = true;
            else
                itemChecked[position] = false;
        }
    });

    return convertView;

........

@Override
public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) {
    // TODO Auto-generated method stub
    CheckBox cb = (CheckBox) v.findViewById(R.id.checkBox1);
    TextView tv = (TextView) v.findViewById(R.id.textView1);
    pi = (PackageInfo) arg0.getItemAtPosition(position);
    cb.performClick();
    if (cb.isChecked()) {
        checkedValue.add(tv.getText().toString());
    } else if (!cb.isChecked()) {
        checkedValue.remove(tv.getText().toString());
    }
}
ArK
  • 20,698
  • 67
  • 109
  • 136
Hardik Thummar
  • 61
  • 1
  • 1
  • 4
-1

Just add following override method in your adapter class:

I was having the same issue, it worked for me:

   @Override
    public int getItemViewType(int position) {
        return position;
    } 
Ali
  • 2,702
  • 3
  • 32
  • 54