05 RecyclerView-布局过程

作者: 凤邪摩羯 | 来源:发表于2021-07-20 09:16 被阅读0次

前言

本文中,我将从RecyclerView插入Item 和 删除Item的两个场景,通过dispatchLayoutStep1、dispatchLayoutStep2、dispatchLayoutStep3各个阶段下来说明RecyclerView的布局情况。


场景1:插入Item

1.1 场景说明

假设在Item1下面插入两条数据AddItem1,AddItem2 图片

1.2 核心方法

notifyItemInserted()

1.3 各个阶段布局情况

阶段1:dispatchLayoutStep1()

  1. 寻找锚点,找到Item1 图片
  2. 移除屏幕上的Views,放入到mAttachedScrap中 图片
  3. 锚点处从上往下填充 图片
  4. 锚点处从下往上填充,由上图可知,上面没有空间了,不填充

  5. 判断是否还有剩余的空间,如果有在末尾填充,下面没空间了,不填充

  6. 因为当前是预布局阶段,不填充

阶段2:dispatchLayoutStep2()

  1. 寻找锚点,找到Item1 图片
  2. 移除屏幕上的Views,放入到mAttachedScrap中 图片
  3. 锚点处从上往下填充,此时将变化后的数据填充到屏幕上,addItem1和addItem2被填充到item1下面 图片
  4. 锚点处从下往上填充,由图可知,没有空间不填充

  5. 判断是否还有剩余的空间,由图可知,没有空间不填充

  6. 当前是layoutStep2阶段,会将mAttachScrap的内容,填充到屏幕末尾,ViewHolder5和ViewHolder6对应的ItemView被填充

图片

阶段3:dispatchLayoutStep3阶段

  1. Item2、Item3~Item6做移动动画
  2. addItem1、addItem2做淡入动画
  3. 动画结束后Item5、Item6被回收到mCachedViews缓存池中
图片

1.4 总结

在Item1下面增加两个Item场景,各个layout阶段的布局情况

图片

场景2:删除Item

2.1 场景说明

屏幕上有Item1-Item6,共6个View,目前需删除Item1和Item2。 图片

2.2 核心方法

notifyItemRemoved()

2.3 各个阶段布局情况

  1. 将Item1 Item2对应的ViewHolder设置为REMOVE状态
  2. 将所有的Item对应的ViewHolder的mPreLayoutPosition字段赋值为当前的position

我们回顾以下onLayoutChildren的几个步骤

  1. 寻找填充的锚点(最终调用findReferenceChild方法)
  2. 移除屏幕上的Views(最终调用detachAndScrapAttachedViews方法)
  3. 从锚点处从上往下填充(调用fill和layoutChunk方法)
  4. 从锚点处从下往上填充(调用fill和layoutChunk方法)
  5. 如果还有多余的空间,继续填充(调用fill和layoutChunk方法)
  6. 非预布局,将scrapList中多余的ViewHolder填充(调用layoutForPredictiveAnimations)

阶段1:dispatchLayoutStep1()

  1. 寻找填充的锚点,寻找锚点的逻辑是,从上往下,找到第一个非remove状态的Item。在本Case中,找到Item3 图片
  2. 移除屏幕上的Views,将它们的ViewHolder放入到Recycler的mAttachedScrap缓存中,这个缓存的好处是如果position对应上了,无需重新绑定,直接拿来用。 图片
  3. 从锚点Item3处往下填充,mAttachedScrap只剩下ViewHolder2和ViewHolder1 图片
  4. 从锚点Item3处往上填充Item2 Item1,因为Item2,Imte1已经被remove掉了,它消耗的空间不会被记录,那么到步骤5的时候还可以填充 图片
  5. 还有多余的空间,继续填充,把Item7、Item8填充到屏幕中 图片
  6. 因为当前是预布局,直接返回

至此step1的layout结束

阶段2:dispatchLayoutStep2阶段

  1. 寻找填充的锚点,寻找锚点的逻辑是,从上往下,找到第一个非remove状态的Item。在本Case中,找到Item3 图片
  2. 移除屏幕上的Views,将它们的ViewHolder放入到Recycler的mAttachedScrap缓存中 图片
  3. 从锚点Item3处往下填充,填充到Item6为止,就没有足够的距离了,mAttachedScrap只剩下ViewHolder8,ViewHolder7,ViewHolder2,ViewHolder1 图片
  4. 往上填充,虽然此时还有两个View的高度,但是此时,上边没有数据了,此处不填充 图片
  5. 此时还有两个View的高度,继续往下填充 图片

「注意此时已经布局完成但是屏幕上部与第一个有GAP,会修复」

 if (getChildCount() > 0) {            // because layout from end may be changed by scroll to position            // we re-calculate it.            // find which side we should check for gaps.            if (mShouldReverseLayout ^ mStackFromEnd) {                int fixOffset = fixLayoutEndGap(endOffset, recycler, state, true);                startOffset += fixOffset;                endOffset += fixOffset;                fixOffset = fixLayoutStartGap(startOffset, recycler, state, false);                startOffset += fixOffset;                endOffset += fixOffset;            } else {                int fixOffset = fixLayoutStartGap(startOffset, recycler, state, true);                startOffset += fixOffset;                endOffset += fixOffset;                fixOffset = fixLayoutEndGap(endOffset, recycler, state, false);                startOffset += fixOffset;                endOffset += fixOffset;            }        }
修复后效果如下 图片
  1. 当前不是预布局,但是因为ViewHolder1和ViewHolder2都是被Remove掉的,所以跳过 图片

阶段3:dispatchLayoutStep3阶段

  1. Item1、Item2做消失动画
  2. Item3、Item4~Item8做移动动画
  3. 动画结束后,Item1、Item2会被回收到mCachedViews缓存池中 图片

2.4 总结

图片

至此,关于RecyclerView布局过程讲解完毕。

相关文章

  • 05 RecyclerView-布局过程

    前言 本文中,我将从RecyclerView插入Item 和 删除Item的两个场景,通过dispatchLayo...

  • 05 RecyclerView-布局原理

    前言 本文主要通过以下两个方面来讲解RecyclerView的布局原理: 布局放置:dispatchLayout(...

  • RecyclerView-实现多布局

    在安卓开发中,随着业务的丰富,在列表数据展示中,布局多样式很常见,如下图所示: 第一步:拿到UI页面之后不要慌,分...

  • UI界面练习(临摹)

    第75天(2018-05-31) 个人中心页面临摹练习。 总结:在临摹过程中注意:排版、颜色、布局。

  • Day05

    Day05 fragment传值 方法一 fragment布局一 acticity布局 java代码 Fragme...

  • 1.布局过程之测量阶段

    1.什么是布局过程 布局是计算控件大小和位置的过程。 布局过程分为两个阶段 测量阶段计算控件及其子控件的大小 布局...

  • 自定义View 自定义布局

    自定义View布局 自定义View布局的工作内容 View或者ViewGroup的布局过程 布局过程自定义的方式 ...

  • 阿里高级Android面试题解析:Android自定义View—

    自定义分三部分绘制、布局和触摸反馈,本篇主要讲的布局过程的自定义 布局过程的含义 布局过程,就是程序在运行时利用布...

  • Recyclerview-优化咸鱼

    逛闲鱼,发现消息里用的recyclerview貌似有些小问题需要优化。顺便带着问题学习一下recyclerview...

  • Recyclerview-局部刷新

    Recyclerview 无脑刷新 notifyDataSetChanged notifyDataSetChang...

网友评论

    本文标题:05 RecyclerView-布局过程

    本文链接:https://www.haomeiwen.com/subject/ngijfltx.html