Android RecyclerView:notifyDataSetChanged()IllegalStateException

 一个人跳舞__的绣绣 发布于 2022-12-10 10:24

我正在尝试使用notifyDataSetChanged()更新recycleview的项目.

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

@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();
        }
    });
}

我选中一个复选框后,我想要做的是更新列表项.我得到了一个非法的例外:"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(),同样的例外.任何秘密的更新方式,以通知适配器的东西发生了变化?

7 个回答
  • UsingaHandlerforaddingitemsandcallingnotify()fromthisHandlerfixedtheissueforme.
    2022-12-11 01:55 回答
  • 找到一个简单的解决方

    public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
    
        private RecyclerView mRecyclerView; 
    
        @Override
        public void onAttachedToRecyclerView(RecyclerView recyclerView) {
            super.onAttachedToRecyclerView(recyclerView);
            mRecyclerView = recyclerView;
        }
    
        private CompoundButton.OnCheckedChangeListener checkedChangeListener 
        = (compoundButton, b) -> {
            final int position = (int) compoundButton.getTag();
            // This class is used to make changes to child view
            final Event event = mDataset.get(position);
            // Update state of checkbox or some other computation which you require
            event.state = b;
            // we create a runnable and then notify item changed at position, this fix crash
            mRecyclerView.post(new Runnable() {
                @Override public void run() {
                    notifyItemChanged(position));
                }
            });
        }
    }
    

    在这里,我们为recyclerview准备好处理它时创建一个可运行的notifyItemChanged.

    2022-12-11 02:13 回答
  • 当您有消息错误时:

    Cannot call this method while RecyclerView is computing a layout or scrolling
    

    简单,只需执行导致异常的原因:

    RecyclerView.post(new Runnable() {
        @Override
        public void run() {
            /** 
            ** Put Your Code here, exemple:
            **/
            notifyItemChanged(position);
        }
    });
    

    2022-12-11 02:13 回答
  • 您应该将方法'setOnCheckedChangeListener()'移动到ViewHolder,它是适配器上的内部类.

    onBindViewHolder()不是初始化的方法ViewHolder.此方法是刷新每个回收物品的步骤.当你打电话时notifyDataSetChanged(),onBindViewHolder()会被称为每个项目的次数.

    因此,如果您notifyDataSetChanged()输入onCheckChanged()并初始化checkBox onBindViewHolder(),则由于循环方法调用,您将获得IllegalStateException.

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

    简单地说,你可以通过在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;
    }
    

    2022-12-11 02:55 回答
  • 我不太清楚,但我也有同样的问题.我通过使用来解决这个onClickListner问题checkbox

    viewHolder.mCheckBox.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if (model.isCheckboxBoolean()) {
                    model.setCheckboxBoolean(false);
                    viewHolder.mCheckBox.setChecked(false);
                } else {
                    model.setCheckboxBoolean(true);
                    viewHolder.mCheckBox.setChecked(true);
                }
                notifyDataSetChanged();
            }
        });
    

    试试这个,这可能会有所帮助!

    2022-12-11 02:58 回答
  • protected void postAndNotifyAdapter(final Handler handler, final RecyclerView recyclerView, final RecyclerView.Adapter adapter) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    if (!recyclerView.isComputingLayout()) {
                        adapter.notifyDataSetChanged();
                    } else {
                        postAndNotifyAdapter(handler, recyclerView, adapter);
                    }
                }
            });
        }
    

    2022-12-11 03:08 回答
  • 您可以在进行更改之前重置上一个侦听器,但不会出现此异常.

    private CompoundButton.OnCheckedChangeListener checkedListener = new CompoundButton.OnCheckedChangeListener() {                      
                            @Override
                            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                                //Do your stuff
                        });;
    
        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position) {
            holder.checkbox.setOnCheckedChangeListener(null);
            holder.checkbox.setChecked(condition);
            holder.checkbox.setOnCheckedChangeListener(checkedListener);
        }
    

    2022-12-11 03:12 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有