huxq17 / XRefreshView

一个万能的android下拉上拉刷新的框架,完美支持recyclerview
1.7k stars 501 forks source link

find a crash #110

Open SilentSword2020 opened 7 years ago

SilentSword2020 commented 7 years ago

android.support.v7.widget.LinearLayoutManager cannot be cast to android.support.v7.widget.StaggeredGridLayoutManager

XRefreshContentView:

public void getRecyclerViewInfo(LayoutManager layoutManager) { int[] lastPositions = null; if(this.layoutManagerType == null) { if(layoutManager instanceof GridLayoutManager) { this.layoutManagerType = XRefreshContentView.LAYOUT_MANAGER_TYPE.GRID; } else if(layoutManager instanceof LinearLayoutManager) { this.layoutManagerType = XRefreshContentView.LAYOUT_MANAGER_TYPE.LINEAR; } else { if(!(layoutManager instanceof StaggeredGridLayoutManager)) { throw new RuntimeException("Unsupported LayoutManager used. Valid ones are LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager"); }

            this.layoutManagerType = XRefreshContentView.LAYOUT_MANAGER_TYPE.STAGGERED_GRID;
        }
    }

    this.mTotalItemCount = layoutManager.getItemCount();
    switch(null.$SwitchMap$com$andview$refreshview$XRefreshContentView$LAYOUT_MANAGER_TYPE[this.layoutManagerType.ordinal()]) {
    case 1:
        this.mVisibleItemCount = layoutManager.getChildCount();
        this.mLastVisibleItemPosition = ((LinearLayoutManager)layoutManager).findLastVisibleItemPosition();

//TODO no break ????????????????????????????????????????????????????????????? case 2: this.mLastVisibleItemPosition = ((LinearLayoutManager)layoutManager).findLastVisibleItemPosition(); this.mFirstVisibleItem = ((LinearLayoutManager)layoutManager).findFirstVisibleItemPosition(); break; case 3: StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager)layoutManager; if(lastPositions == null) { lastPositions = new int[staggeredGridLayoutManager.getSpanCount()]; }

        staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions);
        this.mLastVisibleItemPosition = this.findMax(lastPositions);
        staggeredGridLayoutManager.findFirstVisibleItemPositions(lastPositions);
        this.mFirstVisibleItem = this.findMin(lastPositions);
    }

}
SilentSword2020 commented 7 years ago

java.lang.ClassCastException: android.support.v7.widget.LinearLayoutManager cannot be cast to android.support.v7.widget.StaggeredGridLayoutManager at com.andview.refreshview.XRefreshContentView.getRecyclerViewInfo(XRefreshContentView.java:520) at com.andview.refreshview.XRefreshContentView.onRecyclerViewScrolled(XRefreshContentView.java:158) at com.andview.refreshview.XRefreshContentView$2.onScrolled(XRefreshContentView.java:225) at android.support.v7.widget.RecyclerView.dispatchOnScrolled(RecyclerView.java:4618) at android.support.v7.widget.RecyclerView.dispatchLayoutStep3(RecyclerView.java:3679) at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3323) at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3844) at android.view.View.layout(View.java:17201) at android.view.ViewGroup.layout(ViewGroup.java:5579) at com.andview.refreshview.XRefreshView.onLayout(XRefreshView.java:365) at android.view.View.layout(View.java:17201) at android.view.ViewGroup.layout(ViewGroup.java:5579) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:396) at android.widget.FrameLayout.onLayout(FrameLayout.java:333) at android.view.View.layout(View.java:17201) at android.view.ViewGroup.layout(ViewGroup.java:5579) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:396) at android.widget.FrameLayout.onLayout(FrameLayout.java:333) at android.view.View.layout(View.java:17201) at android.view.ViewGroup.layout(ViewGroup.java:5579) at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:437) at android.view.View.layout(View.java:17201) at android.view.ViewGroup.layout(ViewGroup.java:5579) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:396) at android.widget.FrameLayout.onLayout(FrameLayout.java:333) at android.view.View.layout(View.java:17201) at android.view.ViewGroup.layout(ViewGroup.java:5579) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:2001) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1844) at android.widget.LinearLayout.onLayout(LinearLayout.java:1753) at android.view.View.layout(View.java:17201) at android.view.ViewGroup.layout(ViewGroup.java:5579) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:396) at android.widget.FrameLayout.onLayout(FrameLayout.java:333) at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:2768) at android.view.View.layout(View.java:17201) at android.view.ViewGroup.layout(ViewGroup.java:5579) at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2625) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2278) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1340) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6874) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:902) at android.view.Choreographer.doCallbacks(Choreographer.java:704) at android.view.Choreographer.doFrame(Choreographer.java:636) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:888) at android.os.Handler.handleCallback(Handler.java:815) at android.os.Handler.dispatchMessage(Handler.java:104) at android.os.Looper.loop(Looper.java:207) at android.app.ActivityThread.main(ActivityThread.java:5966) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)

SilentSword2020 commented 7 years ago

public void getRecyclerViewInfo(RecyclerView.LayoutManager layoutManager) { int[] lastPositions = null; if (layoutManagerType == null) { if (layoutManager instanceof GridLayoutManager) { layoutManagerType = LAYOUT_MANAGER_TYPE.GRID; } else if (layoutManager instanceof LinearLayoutManager) { layoutManagerType = LAYOUT_MANAGER_TYPE.LINEAR; } else if (layoutManager instanceof StaggeredGridLayoutManager) { layoutManagerType = LAYOUT_MANAGER_TYPE.STAGGERED_GRID; } else { throw new RuntimeException( "Unsupported LayoutManager used. Valid ones are LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager"); } } mTotalItemCount = layoutManager.getItemCount(); switch (layoutManagerType) { case LINEAR: mVisibleItemCount = layoutManager.getChildCount(); mLastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition(); case GRID: //?????????????????????? LinearLayoutManager ????? mLastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition(); mFirstVisibleItem = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition(); break; case STAGGERED_GRID: StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager; if (lastPositions == null) lastPositions = new int[staggeredGridLayoutManager.getSpanCount()];

            staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions);
            mLastVisibleItemPosition = findMax(lastPositions);

            staggeredGridLayoutManager
                    .findFirstVisibleItemPositions(lastPositions);
            mFirstVisibleItem = findMin(lastPositions);
            break;
    }
}
huxq17 commented 7 years ago

GridLayoutManager extends LinearLayoutManager,所以会那么写,能给个有问题的demo么,没看懂为什么会出错。

SilentSword2020 commented 7 years ago

之前指出的地方没有问题,可能导致崩溃原因和情景是 一个RecyclerView动态切换不同类型的layoutManager 由于代码里,缓存了layoutManagerType 值,没有同步更新 layoutManager对应的类型 layoutManagerType:如果不为空,没有去重新判断新的类型,使用旧的类型,和layoutManager不能一一对应