我正在尝试使用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(),同样的异常。有任何 secret 方法可以更新以通知适配器某些更改吗?
最佳答案
您应该将方法“setOnCheckedChangeListener()”移至ViewHolder,后者是适配器上的内部类。onBindViewHolder()
不是初始化ViewHolder
的方法。
此方法是刷新每个回收站项目的步骤。
当您调用notifyDataSetChanged()
时,onBindViewHolder()
将被称为每个项目的次数。
因此,如果将notifyDataSetChanged()
放入onCheckChanged()
并在onBindViewHolder()
中初始化checkBox,则由于循环方法调用,您将获得IllegalStateException。
单击复选框-> onCheckedChanged()-> notifyDataSetChanged()-> onBindViewHolder()->设置复选框-> onChecked ...
只需将一个标志放入适配器即可解决此问题。
试试这个,
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;
}