Android RecyclerView:notifyDataSetChanged() IllegalStateException [英] Android RecyclerView : notifyDataSetChanged() IllegalStateException

查看:26
本文介绍了Android RecyclerView:notifyDataSetChanged() IllegalStateException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 notifyDataSetChanged() 更新回收视图的项目.

I'm trying to update the items of a recycleview using notifyDataSetChanged().

这是我在 recycleview 适配器中的 onBindViewHolder() 方法.

This is my onBindViewHolder() method in the recycleview adapter.

@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {

     //checkbox view listener
    viewHolder.getCheckbox().setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

            //update list items
            notifyDataSetChanged();
        }
    });
}

我想要做的是在选中复选框后更新列表项.但是我得到了一个非法异常:RecyclerView 正在计算布局或滚动时不能调用这个方法"

What I want to do is update the list items, after I check a checkbox. I get an illegal exception though: "Cannot call this method while RecyclerView is computing a layout or scrolling"

java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling
    at android.support.v7.widget.RecyclerView.assertNotInLayoutOrScroll(RecyclerView.java:1462)
    at android.support.v7.widget.RecyclerView$RecyclerViewDataObserver.onChanged(RecyclerView.java:2982)
    at android.support.v7.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:7493)
    at android.support.v7.widget.RecyclerView$Adapter.notifyDataSetChanged(RecyclerView.java:4338)
    at com.app.myapp.screens.RecycleAdapter.onRowSelect(RecycleAdapter.java:111)

我也使用了notifyItemChanged(),同样的异常.有什么秘密方法可以更新以通知适配器发生了变化?

I also used notifyItemChanged(), same exception. Any secret way to update to notify the adapter that something changed?

推荐答案

您应该将方法 'setOnCheckedChangeListener()' 移动到 ViewHolder,它是您的适配器的内部类.

You should move method 'setOnCheckedChangeListener()' to ViewHolder which is inner class on your adapter.

onBindViewHolder() 不是初始化 ViewHolder 的方法.此方法是刷新每个回收站项目的步骤.当您调用notifyDataSetChanged() 时,onBindViewHolder() 将作为每个项目的次数被调用.

onBindViewHolder() is not a method that initialize ViewHolder. This method is step of refresh each recycler item. When you call notifyDataSetChanged(), onBindViewHolder() will be called as the number of each item times.

因此,如果您将 notifyDataSetChanged() 放入 onCheckChanged() 并在 onBindViewHolder() 中初始化 checkBox,则会因为循环而得到 IllegalStateException方法调用.

So If you notifyDataSetChanged() put into onCheckChanged() and initialize checkBox in onBindViewHolder(), you will get IllegalStateException because of circular method call.

单击复选框 -> onCheckedChanged() -> notifyDataSetChanged() -> onBindViewHolder() -> 设置复选框 -> onChecked...

click checkbox -> onCheckedChanged() -> notifyDataSetChanged() -> onBindViewHolder() -> set checkbox -> onChecked...

简单地说,您可以通过在适配器中放置一个标志来解决此问题.

Simply, you can fix this by put one flag into Adapter.

试试这个,

private boolean onBind;

public ViewHolder(View itemView) {
    super(itemView);
    mCheckBox = (CheckBox) itemView.findViewById(R.id.checkboxId);
    mCheckBox.setOnCheckChangeListener(this);
}

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    if(!onBind) {
        // your process when checkBox changed
        // ...

        notifyDataSetChanged();
    }
}

...

@Override
public void onBindViewHolder(YourAdapter.ViewHolder viewHolder, int position) {
    // process other views 
    // ...

    onBind = true;
    viewHolder.mCheckBox.setChecked(trueOrFalse);
    onBind = false;
}

这篇关于Android RecyclerView:notifyDataSetChanged() IllegalStateException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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