一个ViewPager+Fragment嵌入RecyclerView的结构,进入下层activity返回的时候切换页面就会崩溃,报错信息如下
java.lang.NullPointerException
at androidx.recyclerview.widget.StaggeredGridLayoutManager.recycleFromEnd(StaggeredGridLayoutManager.java:1954)
at androidx.recyclerview.widget.StaggeredGridLayoutManager.recycle(StaggeredGridLayoutManager.java:1788)
at androidx.recyclerview.widget.StaggeredGridLayoutManager.fill(StaggeredGridLayoutManager.java:1707)
at androidx.recyclerview.widget.StaggeredGridLayoutManager.scrollBy(StaggeredGridLayoutManager.java:2180)
at androidx.recyclerview.widget.StaggeredGridLayoutManager.scrollVerticallyBy(StaggeredGridLayoutManager.java:2039)
at androidx.recyclerview.widget.RecyclerView.scrollStep(RecyclerView.java:1855)
at androidx.recyclerview.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:5281)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5039)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:861)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:677)
at dalvik.system.NativeStart.main(Native Method)
看报错堆栈信息,错误不是项目的代码直接奔溃,而是触发了系统的bug,是RecyclerView在detached from window之后仍然进行滚动造成的,由于RecyclerView的scrollStep无法重写,所以要从StaggeredGridLayoutManager入手,而它的scrollVerticallyBy是public的,因此只要在detached状态下直接return 0;
就行了,具体代码如下
class MyStaggeredGridLayoutManager extends StaggeredGridLayoutManager {
private boolean mViewDetached = false;
public void setViewDetached(boolean viewDetached) {
this.mViewDetached = viewDetached;
}
@Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
if (mViewDetached)
return 0;
return super.scrollVerticallyBy(dy, recycler, state);
}
}
同时修改RecyclerView代码控制detached状态
MyStaggeredGridLayoutManager mLayoutManager;
@Override
protected void onDetachedFromWindow() {
if (mLayoutManager != null) {
mLayoutManager.setViewDetached(true);
}
super.onDetachedFromWindow();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (mLayoutManager != null) {
mLayoutManager.setViewDetached(false);
}
}
我要评论