CoordinatorLayout/AppBarLayout记录滚动位置异常问题

记录一下这个比较生僻的知识点,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该方法中进行赋值的,看到这两个方法是不是很熟悉啊,这个不就是保存状态跟恢复状态吗,那为什么会不调用呢,我们再继续找下去。

CoordinatorLayout/AppBarLayout记录滚动位置异常问题_第1张图片

第三步,我们继续跟踪到底是哪里拦截了,没有调用该方法呢?

我们跟踪到android.view.View#dispatchSaveInstanceState该分发保存方法中,mID != NO_ID,恍然大悟呀,原来是因为没有设置id,导致view保存失败,所以无法记录滚动位置。  CoordinatorLayout/AppBarLayout记录滚动位置异常问题_第2张图片

开发中遇到该问题,比较生僻,望与君共勉!!!点赞关注哦!!!

你可能感兴趣的:(android,android,view,AppBarLayout,saveInstance)