Strange RecyclerView复选框onCheckChanged行为 [英] Strange RecyclerView Checkbox onCheckChanged Behavior

查看:203
本文介绍了Strange RecyclerView复选框onCheckChanged行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在工作,我在 RecyclerView 项目中有checkboxe。我知道其中的一些问题。但是,只有10个项目,没有滚动错误的监听器。

I am working where I have checkboxe inside RecyclerView items. I am aware of some of its issues. But, with only 10 items and no scrolling wrong listener is called.

我有这样的:

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我的列表只有10个项目,并且适合在recyclelerview,没有滚动。我从外部更改数据(项目和检查列表),设置新的数据,并调用 myAdapter .notifyDatasetChanged()

Now, strangely this checkedChange calls are made on different views. I have a list of only 10 items and are fit in the recyclerview, no scrolling. I externally change the data (items and checked list), set the new data and calling myAdapter.notifyDatasetChanged()

此调用将从已选状态中删除一个项目。

This call removes one more item from the checked state.

例如,我有10个项目都被检查。我取消选择1项,并基于它和一些其他计算并调用 myAdapter.notifyDatasetChanged()

For example, I have 10 items all checked. I uncheck 1 item, and doing some other calculations based on that and calling myAdapter.notifyDatasetChanged(). It also unchecks one more element from the other 9 items.

因此,即使没有滚动,为什么onCheckedChange侦听器被调用为错误的视图?

So even without scrolling why onCheckedChange listener is called for the wrong view?

推荐答案

我发现了问题。我认为 onBindViewHolder 被调用每个视图来改变数据。但我错了。

I have found out the problem. I thought onBindViewHolder is called for every view to change the data. But I was wrong.

notifyDatasetChanged()回收屏幕上的所有视图持有者,并从回收视图持有者池中随机选择观看者绑定新数据。因此,当我调用 notifyDatasetChanged 时,视图持有者在不同的位置使用,因此更改了一个项目。

notifyDatasetChanged() recycles all the view holders on screen and from the recycled view holder pool randomly viewholders are picked to bind the new data. So when I called the notifyDatasetChanged, the viewholder was used at the different position, and thus changed one more item.

所以,我将回收器视图的 onViewRecycled 方法中的侦听器删除为null。像这样:

So, I removed the listener to null in onViewRecycled method of the recycler view. Like this:

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

        holder.vChecked.setOnCheckedChangeListener(null);
    }

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

This, did solved the issue. I was aware of this, but I thought viewholders are reused for the same position if there is no scrolling. But onDatasetChanged recycles all currently used view holders and uses it again from the random pool.

这篇关于Strange RecyclerView复选框onCheckChanged行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆