Получил ArrayIndexOutOfBoundsException при прокрутке RecyclerView с помощью GridLayoutManager

Я использую RecyclerView (com.android.support:recyclerview-v7:21.0.2) с GridLayoutManager и применяю динамическое количество столбцов . Когда представление прокручивается, возникает исключение. Кажется, ошибка возникает, когда RecyclerView собирается отображать элементы, которые не отображались ранее (повторное использование или перепривязка). Однако, если я не использую такое динамическое количество диапазонов/столбцов или просто комментирую строку, вызывающую GridLayoutManager.setSpanCount, этого не происходит.

Я попытался проверить исходный код, похоже проблема связана с временным массивом 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)

Как решить эту проблему, чтобы у меня была сетка с динамическим счетчиком пролетов? Спасибо.


person fikr4n    schedule 01.12.2014    source источник


Ответы (1)


Мой обходной путь для этой проблемы — настроить размер mSet. Сделал это, расширив 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;
        }
    }
}
person ulcica    schedule 27.02.2015
comment
Это было так давно, но это решение стоит попробовать в будущем. Спасибо. - person fikr4n; 28.02.2015
comment
Не работает, потому что mSet является локальным пакетом и не может быть доступен снаружи пакета - person Marian Klühspies; 11.01.2017
comment
@MarianKlühspies, нет проблем с помещением дочернего класса в пакет android.support.v7.widget. Попробуйте! Оно работает ;) - person ulcica; 11.01.2017
comment
Вы вообще знаете, почему это происходит? В моем случае это из-за нативной рекламы, но только иногда, если интернет-соединение очень плохое. - person Marian Klühspies; 11.01.2017