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)
出現問題的代碼地方html
helper.getView<CheckBox>(R.id.selecte_state).setOnCheckedChangeListener { buttonView, isChecked -> if (isChecked) { adapter.notifyDataSetChanged() } }
在checkbox裏面設置了狀態監聽,而後調用了notifyDataSetChanged()出現的java
錯誤日誌第一行的方法android
assertNotInLayoutOrScroll
咱們看下源碼app
/** * 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加載好或者用handlerpost
處理ui
2 解決辦法
方法一、this
helper.getView<CheckBox>(R.id.selecte_state).setOnCheckedChangeListener { buttonView, isChecked -> if (isChecked) { Handler().post(Runnable { selectedIndex = position listener(helper.itemView, item!!.languageIndex) }) } }
方法二、spa
helper.getView<CheckBox>(R.id.selecte_state).setOnCheckedChangeListener { buttonView, isChecked -> if (isChecked) { recycleView.post(Runnable { selectedIndex = position listener(helper.itemView, item!!.languageIndex) }) } }