android - 奇怪的 RecyclerView 复选框 onCheckChanged 行为

标签 android checkbox android-recyclerview

我在 RecyclerView 项目中有复选框的地方工作。我知道它的一些问题。但是,只有 10 个项目并且没有滚动错误的监听器被调用。

我有这样的东西:

private class MyAdapter extends RecyclerView.Adapter<MyViewHodler> {
    ArrayList<String> items;
    ArrayList<String> checkedList = new ArrayList<>();
    ...

    public void onBindViewHolder(final MyViewHolder holder, int position) {
        String item = items.get(position);
        String check = checkedList.get(item);
        if(check != null)
            holder.vChecked.setChecked(true);
        else
            holder.vChecked.setChecked(false);

        ....

        holder.vChecked.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
                    if (isChecked) {
                        checkedList.add(item);
                    } else {
                        checkedList.remove(item);
                    }
                }
    }

}

现在,奇怪的是这个 checkedChange 调用是在不同的 View 上进行的。我有一个只有 10 个项目的列表并且适合 recyclerview,没有滚动。我在外部更改数据(项目和检查列表),设置新数据并调用 myAdapter.notifyDatasetChanged()

此调用从选中状态中删除了一项。

例如,我有 10 个项目都已检查。我取消选中 1 个项目,并根据该项目进行一些其他计算并调用 myAdapter.notifyDatasetChanged()。它还从其他 9 个项目中取消选中另一个元素。

那么即使没有滚动,为什么会为错误的 View 调用 onCheckedChange 监听器?

最佳答案

我发现了问题。我以为每个 View 都会调用 onBindViewHolder 来更改数据。但是我错了。

notifyDatasetChanged() 回收屏幕上的所有 View 持有者,并从回收的 View 持有者池中随机挑选 View 持有者来绑定(bind)新数据。所以当我调用 notifyDatasetChanged 时,viewholder 被用在不同的位置,因此又改变了一项。

因此,我在回收器 View 的 onViewRecycled 方法中删除了对 null 的监听器。像这样:

    @Override
    public void onViewRecycled(MyViewHolder holder) {
        super.onViewRecycled(holder);

        holder.vChecked.setOnCheckedChangeListener(null);
    }

这样,确实解决了问题。我知道这一点,但我认为如果没有滚动,viewholders 会被重复用于同一位置。但是 onDatasetChanged 回收所有当前使用的 View 持有者并从随机池中再次使用它。

关于android - 奇怪的 RecyclerView 复选框 onCheckChanged 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38543196/

相关文章:

android - 为什么不是所有来自 FirebaseDatabase 引用的数据都添加到 ArrayList<String> 中?

android - GBoard 外的贴纸包

android - 如何将位图覆盖在另一个位图上

php - 如何在 WordPress 小部件中保存复选框数组?

javascript - 使用一个复选框显示/隐藏全部或切换多个 div

android - 如何在 MVVM 结构中的 RecyclerView 项目上设置 OnClickListener

android - DialogFragment 忽略 OnBackPressedDispatcher

jquery - 使用 jQuery 哪个事件属于 "type text into textfield"

android - 如何像垂直 Viewpager 变换一样为 RecyclerView 设置动画

android - 添加评论时更新 RecyclerView