1 问题
java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling androidx.recyclerview.widget.RecyclerView{24d6f3b VFED.V... ......ID 0,657-1074,1911 #7f090143 app:id/recyclerView}, adapter:com.appsinnova.android.keepshare.widget.PopupLanguage$LanguageListAdapter@57e8658, layout:androidx.recyclerview.widget.LinearLayoutManager@3de33b1, context:com.appsinnova.android.keepshare.account.SettingActivity@4b834ad
at androidx.recyclerview.widget.RecyclerView.assertNotInLayoutOrScroll(RecyclerView.java:3051)
at androidx.recyclerview.widget.RecyclerView$RecyclerViewDataObserver.onChanged(RecyclerView.java:5536)
at androidx.recyclerview.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:12253)
at androidx.recyclerview.widget.RecyclerView$Adapter.notifyDataSetChanged(RecyclerView.java:7354)
at com.appsinnova.android.keepshare.widget.PopupLanguage$LanguageListAdapter$convert$1.onCheckedChanged(PopupLanguage.kt:108)
at android.widget.CompoundButton.setChecked(CompoundButton.java:171)
at com.appsinnova.android.keepshare.widget.PopupLanguage$LanguageListAdapter.convert(PopupLanguage.kt:104)
at com.appsinnova.android.keepshare.widget.PopupLanguage$LanguageListAdapter.convert(PopupLanguage.kt:98)
at com.chad.library.adapter.base.BaseQuickAdapter.onBindViewHolder(BaseQuickAdapter.java:937)
at com.chad.library.adapter.base.BaseQuickAdapter.onBindViewHolder(BaseQuickAdapter.java:66)
at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7065)
at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7107)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6012)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6279)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114)
at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851)
at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404)
at android.view.View.layout(View.java:21112)
at android.view.ViewGroup.layout(ViewGroup.java:6400)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1828)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1656)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1565)
at android.view.View.layout(View.java:21112)
出现问题的代码地方
helper.getView<CheckBox>(R.id.selecte_state).setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
adapter.notifyDataSetChanged()
}
}
在checkbox里面设置了状态监听,然后调用了notifyDataSetChanged()出现的
错误日志第一行的方法
assertNotInLayoutOrScroll
我们看下源码
/**
* Checks if RecyclerView is in the middle of a layout or scroll and throws an
* {@link IllegalStateException} if it <b>is</b>.
*
* @param message The message for the exception. Can be null.
* @see #assertInLayoutOrScroll(String)
*/
void assertNotInLayoutOrScroll(String message) {
if (isComputingLayout()) {
if (message == null) {
throw new IllegalStateException("Cannot call this method while RecyclerView is "
+ "computing a layout or scrolling" + exceptionLabel());
}
throw new IllegalStateException(message);
}
if (mDispatchScrollCounter > 0) {
Log.w(TAG, "Cannot call this method in a scroll callback. Scroll callbacks might"
+ "be run during a measure & layout pass where you cannot change the"
+ "RecyclerView data. Any method call that might change the structure"
+ "of the RecyclerView or the adapter contents should be postponed to"
+ "the next frame.",
new IllegalStateException("" + exceptionLabel()));
}
}
我们发现isComputingLayout()这个函数true就抛出这个异常,所以看下这个函数实现
我们可以看到recycleView被lockdown了,我们怎么解决呢?上面也说了,等view加载好或者用handler
处理
2 解决办法
方法1、
helper.getView<CheckBox>(R.id.selecte_state).setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
Handler().post(Runnable {
selectedIndex = position
listener(helper.itemView, item!!.languageIndex)
})
}
}
方法2、
helper.getView<CheckBox>(R.id.selecte_state).setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
recycleView.post(Runnable {
selectedIndex = position
listener(helper.itemView, item!!.languageIndex)
})
}
}