之前的三篇文章的最后说到了三个步骤那就是Measure,Layout,Draw。接下来的三篇文章主要从源码的角度来分析这三个过程的具体实现。

本章主要梳理Layout过程

二、Layout流程分析

我们在这篇文章中说到过,在performTraversals调用了performLayout这个方法,我们查看这个方法的源代码

UI绘制流程的三部曲----Layout

host被赋值为mView,而mView之前说过是mDecorView,而mView对象调用了layout方法,我们继续查看layout方法:

UI绘制流程的三部曲----Layout

一共有三处地方需要我们注意一下:

(1)第一处标记的含义:如果不是第一次,则会跳过这里;如果是第一次会进行一次测量,用于保存宽和高,意义在于优化

(2)第二处标记:在setOpticalFrame中我们发现,最后调用的还是setFrame,所以我们直接查看setFrame的源码:

UI绘制流程的三部曲----Layout

我们发现主要是对t,b,l,r属性的一些操作,我们看这个方法的注释:设定此View的大小和参数,这里我们就很清楚了,主要是对t,b,l,r属性的初始化操作,这个方法的细节操作也不难理解,感兴趣的同学可以自己了解一下

(3)第三处标记:这里是onLayout方法的调用,我们查看onLayout方法

UI绘制流程的三部曲----Layout

发现没有做任何的操作,这是怎么回事呢?底子比较好的同学在这里应该知道是怎么回事,是在其子View中覆写了这个方法,而这时候我们一直所说的View是mDecorView,所以我们在这个类中进行寻找onLayout方法:

UI绘制流程的三部曲----Layout

果然发现了被覆写的onLayout方法,方法中又调用了父类的onLayout方法,DecorView类的父类是FrameLayout

UI绘制流程的三部曲----Layout

所以我们在FrameLayout继续查看onLayout方法:

UI绘制流程的三部曲----Layout

这里呢调用了layoutChildren方法,查看这个方法:

UI绘制流程的三部曲----Layout

这里的代码过长,我截取了一部分,而整体代码呢其实还是比较好理解的,就是在迭代布局中的子View,我们可以总结一下这个方法:

当前我们的组件在不断的迭代当前的子view,然后让她们开始调用自己layout方法进行定位,所以直接从此处可以看出来,当前我们的布局摆放流程实际上是,先得到顶层, 顶层自己先开始layout进行布局定位,然后调用onLayout调用子view让子view调用自己的layout对自己进行定位以达到定位的所有目的

 

总结:
那么其实我门只要清楚了当前的绘制流程和布局流程,我门需要开发自己自定义的布局其实实际上就只需要添加我门自己的业务代码,不管是FreamLayout,还是LinearLayout等官方提供出来的布局组件, 都是依照这套机制来玩的, 只不过是添加了她们的业务,实现了相对应的效果

参考文章

欢迎留言,欢迎纠错,共同进步!

 

 

相关文章: