美文网首页
Cannot call this method while Re

Cannot call this method while Re

作者: space0o0 | 来源:发表于2021-01-06 17:35 被阅读0次

    我的场景

    recyclerview的item 存在checkBox,checkBox的checkChangedListener中会修改数据源,同时调用notifyDataSetChanged函数。

    // Adapter.class 伪代码
    @Override
    public void onBindViewHolder(viewHolder arg0, final int arg1) {
            arg0.checkbox.setChecked(data.get(index).isCheck);
    }
    
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            // 修改数据源
            changeData();
            // 刷新界面
            notifyDataSetChanged();
    }
    

    当持有该adapter的类也修改了数据源,同时调用了notifyDataSetChanged函数,Adapter就会触发onBindViewHolder(),checkBox的check被修改,又触发了onCheckedChanged的监听,这时就会crash。

    // 持有Adapter的外部类        伪代码
    void apiCall(){
            // 更新数据
            data = updateData();
            // 更新UI
            adapter.notifyDataSetChanged();
    }
    
    // crash info
    java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling
    

    crash的本意是RecyclerView正在layout或滚动,无法调用notifyDataSetChanged。

    解决思路

    1、避免在RecyclerView正在computing的时候,调用notifyDataSetChanged函数。使用handler的消息队列机制,当前队列消息正在处理computing,所以,可以向队列post一个notifyDataSetChanged的任务。这样就能避免RecyclerView正在computing

    new Handler().post(new Runnable() {
        @Override
        public void run() {
            notifyDataSetChanged();
        }
    });
    

    2、因为是外部滑动或主动调用了notifyDataSetChanged函数,所以会触发onBindViewHolder,这里会主动的修改checkBox的check。可以在checkBox.setCheck()函数前后添加变量,用来判断是否是正在bind。

    @Override
    public void onBindViewHolder(viewHolder arg0, final int arg1) {
            onBind = true;
            arg0.checkbox.setChecked(data.get(index).isCheck);
            onBind = false;
    }
    
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            // 修改数据源
            changeData();
            // 刷新界面
            if(!onBind){
                notifyDataSetChanged();
            }
    }
    

    推荐使用第一种解决思路。方案二可能存在其他特殊情况,导致各种变量判断,增加了开发难度。

    相关文章

      网友评论

          本文标题:Cannot call this method while Re

          本文链接:https://www.haomeiwen.com/subject/qdhooktx.html