【问题标题】:Got ArrayIndexOutOfBoundsException when scrolling RecyclerView with GridLayoutManager使用 GridLayoutManager 滚动 RecyclerView 时出现 ArrayIndexOutOfBoundsException
【发布时间】:2014-12-01 11:48:54
【问题描述】:

我正在使用RecyclerView (com.android.support:recyclerview-v7:21.0.2) 和GridLayoutManager 并应用dynamic column count。滚动视图时会引发异常。当RecyclerView 即将显示以前未显示的项目(重用或重新绑定)时,似乎会发生错误。但是,如果我不使用这样的动态跨度/列数或简单地注释调用GridLayoutManager.setSpanCount 的行,则不会发生。

我尝试检查source code,似乎问题与临时数组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)

如何解决这个问题,以便我可以拥有一个具有动态跨度计数的网格?谢谢。

【问题讨论】:

    标签: android android-recyclerview gridlayoutmanager


    【解决方案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;
            }
        }
    }
    

    【讨论】:

    • 这么久了,不过这个方案值得以后尝试。谢谢。
    • 不起作用,因为 mSet 是包本地的,无法从包外部访问
    • @MarianKlühspies,将子类放入包android.support.v7.widget是没有问题的。试试看!它有效;)
    • 你真的知道,为什么会这样吗?在我的情况下,这是因为原生广告,但只是有时,如果互联网连接非常糟糕
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-27
    • 2016-02-19
    • 2011-08-05
    • 2015-12-22
    • 2014-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多