Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Got ArrayIndexOutOfBoundsException when scrolling RecyclerView with GridLayoutManager

I am using RecyclerView (com.android.support:recyclerview-v7:21.0.2) with GridLayoutManager and applying dynamic column count. When the view is scrolled an exception is thrown. It seems the error happens when the RecyclerView about to display items that were not displayed previously (reusing or rebinding). However, if I don't use such dynamic span/column count or simply comment the line calling GridLayoutManager.setSpanCount, it does not happen.

I've tried to inspect the source code, it seems the problem is related to a temporary array mSet.

E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.ArrayIndexOutOfBoundsException
            at android.support.v7.widget.GridLayoutManager.layoutChunk(GridLayoutManager.java:361)
            at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1269)
            at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1097)
            at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:957)
            at android.support.v7.widget.RecyclerView.scrollByInternal(RecyclerView.java:985)
            at android.support.v7.widget.RecyclerView.onTouchEvent(RecyclerView.java:1686)
            at android.view.View.dispatchTouchEvent(View.java:3885)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:903)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1691)
            at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1125)
            at android.app.Activity.dispatchTouchEvent(Activity.java:2096)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1675)
            at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2194)
            at android.view.ViewRoot.handleMessage(ViewRoot.java:1878)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:123)
            at android.app.ActivityThread.main(ActivityThread.java:3683)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:507)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
            at dalvik.system.NativeStart.main(Native Method)

How to solve this so that I can have a grid with dynamic span count? Thank you.

like image 930
fikr4n Avatar asked Nov 09 '22 22:11

fikr4n


1 Answers

My workaround for this issue is to adjust the mSet size. Did it by extending GridLayoutManager.

package android.support.v7.widget;


import android.content.Context;
import android.view.View;

public class MyGridLayoutManager extends GridLayoutManager {
    public MyGridLayoutManager(Context context, int spanCount) {
        super(context, spanCount);
    }

    public MyGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
        super(context, spanCount, orientation, reverseLayout);
    }

    @Override
    public void setSpanCount(int spanCount) {
        super.setSpanCount(spanCount);
        if (mSet != null && mSet.length != spanCount) {
            View[] newSet = new View[spanCount];
            System.arraycopy(mSet, 0, newSet, 0, Math.min(mSet.length, spanCount));
            mSet = newSet;
        }
    }
}
like image 78
ulcica Avatar answered Nov 28 '22 06:11

ulcica