Android之提示Cannot call this method while RecyclerView is computing a layout or scrolling

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)
                    })
                }
            }

 

發佈了1083 篇原創文章 · 獲贊 693 · 訪問量 310萬+
相關文章
相關標籤/搜索