记录一下这个比较生僻的知识点,viewpager中嵌套fragment,当fragment中嵌套CoordinatorLayout时,当再次切回来,发现CoordinatorLayout没有记录对应的滚动位置。
先附解决方案,由于CoordinatorLayout/AppBarLayout没有设置id导致,设置id后就可以正常记录位置了。
为什么会出现这种问题,那必须是源码走起,我们一起看下去。。。。
第一步,首先要想记录滚动位置,那么AppBarLayout的偏移量必须回调才可以,通过这个步骤,我们找到android.support.design.widget.AppBarLayout.BaseBehavior#onLayoutChild该方法。
这里我只贴一下这个该方法的伪代码
- public boolean onLayoutChild(CoordinatorLayout parent, T abl, int layoutDirection) {
-
- int offset;
- if (this.offsetToChildIndexOnLayout >= 0 && (pendingAction & 8) == 0) {
- View child = abl.getChildAt(this.offsetToChildIndexOnLayout);
- offset = -child.getBottom();
- if (this.offsetToChildIndexOnLayoutIsMinHeight) {
- offset += ViewCompat.getMinimumHeight(child) + abl.getTopInset();
- } else {
- offset += Math.round((float)child.getHeight() * this.offsetToChildIndexOnLayoutPerc);
- }
- }
这里offset是关键,但是发现如果想进入if设置offset,offsetToChildIndexOnLayout这个值始终是-1,那么接下来我们找offsetToChildIndexOnLayout该值在哪里赋值的。
第二步,我们发现offsetToChildIndexOnLayout 该值是在android.support.design.widget.AppBarLayout.BaseBehavior#onRestoreInstanceState该方法中进行赋值的,看到这两个方法是不是很熟悉啊,这个不就是保存状态跟恢复状态吗,那为什么会不调用呢,我们再继续找下去。
第三步,我们继续跟踪到底是哪里拦截了,没有调用该方法呢?
我们跟踪到android.view.View#dispatchSaveInstanceState该分发保存方法中,mID != NO_ID,恍然大悟呀,原来是因为没有设置id,导致view保存失败,所以无法记录滚动位置。
开发中遇到该问题,比较生僻,望与君共勉!!!点赞关注哦!!!