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


    记录一下这个比较生僻的知识点,viewpager中嵌套fragment,当fragment中嵌套CoordinatorLayout时,当再次切回来,发现CoordinatorLayout没有记录对应的滚动位置。

    先附解决方案,由于CoordinatorLayout/AppBarLayout没有设置id导致,设置id后就可以正常记录位置了。

    为什么会出现这种问题,那必须是源码走起,我们一起看下去。。。。

    第一步,首先要想记录滚动位置,那么AppBarLayout的偏移量必须回调才可以,通过这个步骤,我们找到android.support.design.widget.AppBarLayout.BaseBehavior#onLayoutChild该方法。

    这里我只贴一下这个该方法的伪代码

    1. public boolean onLayoutChild(CoordinatorLayout parent, T abl, int layoutDirection) {
    2. int offset;
    3. if (this.offsetToChildIndexOnLayout >= 0 && (pendingAction & 8) == 0) {
    4. View child = abl.getChildAt(this.offsetToChildIndexOnLayout);
    5. offset = -child.getBottom();
    6. if (this.offsetToChildIndexOnLayoutIsMinHeight) {
    7. offset += ViewCompat.getMinimumHeight(child) + abl.getTopInset();
    8. } else {
    9. offset += Math.round((float)child.getHeight() * this.offsetToChildIndexOnLayoutPerc);
    10. }
    11. }

    这里offset是关键,但是发现如果想进入if设置offset,offsetToChildIndexOnLayout这个值始终是-1,那么接下来我们找offsetToChildIndexOnLayout该值在哪里赋值的。

    第二步,我们发现offsetToChildIndexOnLayout 该值是在android.support.design.widget.AppBarLayout.BaseBehavior#onRestoreInstanceState该方法中进行赋值的,看到这两个方法是不是很熟悉啊,这个不就是保存状态跟恢复状态吗,那为什么会不调用呢,我们再继续找下去。

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

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

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

  • 相关阅读:
    C++提高编程
    Go语言sync.Map
    使用VitePress搭建及部署vue组件库文档
    Golang Web框架fiber
    Docker Restful API快速入门
    R-CNN、Fast R-CNN和Faster R-CNN:目标检测的进化之路
    「iOS」UI——无限轮播图实现与UIPageControl运用
    聊聊二叉树的前序遍历算法
    【iOS】—— NSOperation、NSOperationQueue
    Python实现XMind测试用例快速转Excel用例
  • 原文地址:https://blog.csdn.net/no_loafer/article/details/133088297