[Solved] Android Warning: Cannot call this method while RecyclerView is computing a layout or scrolling

1 error

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.appsin[email protected]57e8658, layout:[email protected], context:[email protected]
        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)

Where is the problem code

            helper.getView<CheckBox>(R.id.selecte_state).setOnCheckedChangeListener { buttonView, isChecked ->
                if (isChecked) {
					adapter.notifyDataSetChanged()
                }
            }

sets the status listener in checkbox, and then calls

in notifyDataSetChanged ().

Method for the first line of error log

assertNotInLayoutOrScroll

Let’s look at the source code

    /**
     * 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()));
        }
    }

We found that the iscomputinglayout() function is true and throws this exception, so let’s take a look at the implementation of this function

We can see that recycleview is locked down. How can we solve this problem?As mentioned above, wait for the view to load or use the handler

Treatment

2 solutions

Method 1

            helper.getView<CheckBox>(R.id.selecte_state).setOnCheckedChangeListener { buttonView, isChecked ->
                if (isChecked) {
                     Handler().post(Runnable {
                        selectedIndex = position
                        listener(helper.itemView, item!!.languageIndex)
                    })
                }
            }

Method 2

            helper.getView<CheckBox>(R.id.selecte_state).setOnCheckedChangeListener { buttonView, isChecked ->
                if (isChecked) {
                    recycleView.post(Runnable {
                        selectedIndex = position
                        listener(helper.itemView, item!!.languageIndex)
                    })
                }
            }

 

Similar Posts: