Checkbox in RecyclerView index gets clicked twice

问题: I have a RecyclerView list with CheckBox in the CardView, using a simple onClickListener. But when index 0 is clicked index 10 is also shown as clicked. The same if index 1...

问题:

I have a RecyclerView list with CheckBox in the CardView, using a simple onClickListener. But when index 0 is clicked index 10 is also shown as clicked. The same if index 1 is clicked so is 11, index 2 so is 12, and so on. How do I solve this problem?


回答1:

This is because of the behavior of your RecyclerView. RecyclerView tries to recycle the views generated already with minimal changes in data. So in order to populate your data precisely in your list items, you need to tell exactly what it needs to show.

In your case, you need to keep the track of your checkbox click somewhere (maybe in a different array) so that you can populate the views accordingly. Let us consider the following code.

// Let us create an integer array having the same size of your list that is being passed to your RecyclerView
// Initially, all elements in the array is zero. 
private int[] array = new int[yourList.size()]; 

Now in your onBindViewHolder, I think you have implemented the onClickListener for your CheckBox. Hence when you are clicking the CheckBox, set the corresponding element in your array to 1.

public void onClick(int position) {
    // Checbox click action here
    array[position] = 1; // Use the position of your adapter to set the value. 
}

Now in the onBindViewHolder while populating the CheckBox, check the value of its position in the array and set the checked status accordingly.

if(array[position] == 1) checkBox.setChecked(true);
else checkBox.setChecked(false);

Hope that helps!


回答2:

Three steps to solve it, and can be used everywhere you have a checkbox widget and it will be resued.

Firstly, Each adapter has a corresponding 'bean' binds to it. for example, List, The T is the bean.

Secondly, add a boolean field 'ischecked' into 'bean' class.

Finally, use this field to reset the status of checkbox when recycleview reuses checkbox, and update it when status of checkbox being changed.


回答3:

RecyclerView will reuse the layouts from previous rows when scrolling, so if you check item 1, and scroll, item 11 will still be checked unless told to not be.

Within your onBindViewHolder, you want to set the layout to the current state of the object you're displaying.

For example, say we have a list of Dogs, and we can mark if we've pet the Dog.

class Dog {
    public boolean hasPet = false;
    public String name;
}

Now, if you're displaying each Dog, you can do.

void onBindViewHolder(MyViewHolder holde, int position) {
    Dog dog = list[position];
    holder.name = dog.name;

    // Remove any onCheckChangeListener or else we'll change the previously rendered dog.
    holder.check.setOnCheckedChangeListener(null);

    // Set the checkbox to the current state of the dog.
    holder.check.setChecked(dog.hasPet);

    // Add a new onCheckChangeListener with the current dog.
    holder.check.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            Logger.d("Clicked.");
            dog.hasPet = isChecked;
        }
    });
}
  • 发表于 2019-03-07 19:11
  • 阅读 ( 236 )
  • 分类:sof

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除