Android

indexoutofboundsexception staggeredgridlayoutmanaer$span.calculatecachedstart

joong~ 2022. 1. 2. 22:39
728x90

 

indexboundsexception 에러라서 

어디서 get을 가져다 쓰는 줄 알 고 한참 뒤지다가 자세히 다시 보니 staggeredgridlayoutmaanger.calculatecachedstart 에러임

 

일단 구조는

뷰페이저 + 프래그먼트 + 리싸이클러뷰이다.

뷰페이저를 왔다갔따 리싸이클러뷰를 스크롤했따 자꾸 그러면 간헐적으로 발생하는 에러.

 

뷰페이저2를 사용할 때 캐시 수를 설정하지 않았기 때문이다. 뷰페이저가 죽을 때

StaggredGridLayoutManager#onDetachedFromWindow가 호출된다. 이함수는 자주 전환할 때 호출 된다.

    @Override
    public void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycler) {
        super.onDetachedFromWindow(view, recycler);

        removeCallbacks(mCheckForGapsRunnable);
        for (int i = 0; i < mSpanCount; i++) {
            mSpans[i].clear();
        }
        // SGLM will require fresh layout call to recover state after detach
        view.requestLayout();
    }

 

따라서 슬라이드 할 때 calculateCachedStart가 호출 되며 충돌이 발생한다.

        void calculateCachedStart() {
            final View startView = mViews.get(0);
            final LayoutParams lp = getLayoutParams(startView);
            mCachedStart = mPrimaryOrientation.getDecoratedStart(startView);
            if (lp.mFullSpan) {
                LazySpanLookup.FullSpanItem fsi = mLazySpanLookup
                        .getFullSpanItem(lp.getViewLayoutPosition());
                if (fsi != null && fsi.mGapDir == LayoutState.LAYOUT_START) {
                    mCachedStart -= fsi.getGapForSpan(mIndex);
                }
            }
        }

 

따라서 해결방법으로는 뷰페이저의 캐시수를 설정하거나 (setoffscreenpagelist)

onDetachFromWindow를 재정의 하는 방법이 있다.

 

뷰페이저 캐시수를 설정하게 되면 ondetachedfromwindow가 호출되지 않는다. 문제는 해결되지만 시작 중에 많은 페이지들이 초기화되어 시작되기 때문에 속도에 영향을 줄 수 있다.

 

https://stackoverflow.com/questions/44571895/staggeredgridlayoutmanager-calculatecachedstart-indexoutofboundsexception

https://blog.csdn.net/HUandroid/article/details/112672159