阅读本文您大概需要4.33分钟。
相关系列文章
在上一篇文章中主要讲解了RecyclerView内部的大体设计结构。因为是从结构出发,所以多少对细节讲的云里雾里。那么从这一篇开始要落实到代码细节中了。
既然RecyclerView是一个GroupView,那么也就是一个View。那么View的绘制过程是measure到layout到draw的一个顺序。然而一个GroupView的目的是盛放其它View的,那么最主要的还是其measure和layout过程。那么我们今天就来看看RecyclerView的measure过程。
PS:源码版本为24.1.1,如果下面与你的源码有出入,请核实版本是否相同。
RecyclerView的Measure过程
如果你这个时候也打开了源码,你应该会发现RecyclerView的onMeasure方法很长。那么我们先将其分情况讨论。
- 没有LayoutManager的情况
- 有LayoutManager并开启了自动测量
- 有LayoutManager但没有开启自动测量
|
|
第一种情况十分简单,就是执行了defaultOnMeasure方法。里面就是计算并设置了RecyclerView的长宽值。下来我们介绍另外两种情况。
RecyclerView的自动测量过程
在RecyclerView的早期版本,当你为其设置了wrap_content值,但在其中的内容改变的时候,RecyclerView并不能改变其大小来适应内部的内容。因此后来加入了自动测量机制,来解决这个问题。而且现在我们常用的三个LayoutManager,在其构造函数中,均已经设置了开启自动测量。所以我们现在可以放心大胆的为RecyclerView设置wrap_content。
那么我们来看一下RecyclerView的自动测绘过程:
|
|
自动测绘过程可以分为两部分:
第一部分:
- 首先执行LayoutManager的onMeasure方法。
- 检查如果width和height都已经是精确值,那么就不用再根据内容进行计算所需要的width和height,那么跳过之后的步骤。如果有其中任何一个值不是精确值,则进入到下面计算所需长宽的步骤。
第二部分:
- 开启布局流程,计算出所有Child的边界。
- 然后根据计算出的Child的边界计算出RecyclerView的所需width和height,并设置。
- 检查是否需要再次测量,如果需要则在此进行测量。
注意:
因为自动绘制过程中执行了布局流程,那么在之后布局的时候会检查是否已经进行过布局流程,如果已经进行过布局流程,则会跳过进行过的布局流程,不会造成重复操作。(布局流程有三步)
RecyclerView的非自动测绘流程
当我们使用系统提供的那三个LayoutManager的时候,默认是开启自动测绘的。除非,你在初始化LayoutManager之后,自己通过setAutoMeasureEnabled(false)
方法设置成false。不然不会走到非自动测绘流程的。但是如果我们是使用的自己自定义的LayoutManager,而且我们自定义的LayoutManager又没有在初始化的时候开启自动测绘,那么默认将会是不开启自动测绘。这个时候会走到非自动测绘流程。
那么接下来看一看非自动测绘流程。
|
|
RecyclerView的非自动化测绘流程也可以分为两部分:
第一部分:
在固定尺寸模式下,直接执行LayoutManager的onMeasure方法。
第二部分:
不在固定尺寸模式下
- 如果在测量的过程中有数据有更新,则先处理更新的数据
- 执行自定义测量流程,这需要自定义的LayoutManager实现onMeasure方法。
总结
一般情况下,进入的都是自动测量模式。
最不常见的是没有设置LayoutManager的模式。
最后需要注意的是:我们自定义LayoutManager的时候要根据自己的需求,决定是否要开启自动测量。如果需要开启,则要主动调用setAutoMeasureEnabled(true)
,否则默认是不开启的。
感谢您的阅读,如果您觉得本文对你有所帮助,请不要吝啬您的喜欢,您的喜欢是我写作的动力。