Android View框架总结(四)View布局流程之Measure
- View树的measure流程
- View的measures时序图
- View布局流程之measure
- measure过程
- View的measure过程
- ViewGroup的measure过程
- FrameLayout的measure过程
- measure过程
View树的measure流程图如下:
View树的measure时序图:
View的measure过程
View的measure方法如下:
View.java
这是个final方法, 子类不能重写, 主要是在里面会调用onMeasure方法.
此处有一个优化, 就是把MeasureSpec保存, 下次执行measure方法时如果measureSpec不变就不执行measure流程, 除非设置了PFLAG_FORCE_LAYOUT标志, 这个标志就是在requestLayout里面设置的.
onMeasure之后会检查PFLAG_MEASURED_DIMENSION_SET标志, 也就是要求的onMeasure方法里面要调用setMeasuredDimensition方法(注意此方法设置的是尺寸不是MeasureSpec).
看默认的onMeasure方法
这里调用 setMeasuredDimension方法,默认通过getDefaultSize计算宽高. 其中 在看此方法之前,先看getSuggestedMinimumxxx()方法:
getSuggestedMinimumWidth是此View的最小尺寸, 一般是背景图片的尺寸和minWidth/minHeight属性值较大的. 当然也可以重写此方法返回自定义值.
然后看getDefaultSize()方法:
不限定大小则返回自己大小, 否则返回父容器限定的最大值.
结合上面的MeasureSpec我们知道, 如果View的LayoutParams使用wrap_content, 那么它的SpecMode是AT_MOST模式. 这种情况下此View大小是父容器的剩余空间大小, 和match_parent一致了. 因此一般情况下自定义View的子类都需要重新onMeasure方法.
再看setMeasuredDimension方法:
这个方法决定了当前View的大小,也是一个final方法,写自定义控件大小时,重写onMeasure方法,最终都会调用此方法。到此一次最基础的元素View的measure过程就完成了。
View实际是挂在decorView树上的树枝,而且measure是递归的,所以每个View都需要measure。一般能够嵌套的View一般都是ViewGroup的子类,所以在ViewGroup中定义了measureChildren, measureChild, measureChildWithMargins方法来对子视图进行测量,measureChildren内部实质只是循环调用measureChild,measureChild和measureChildWithMargins的区别就是是否把margin和padding也作为子视图的大小。下面分析ViewGroup的measure过程
ViewGroup的measure过程
ViewGroup的measure过程除了完成自己的measure, 还需要遍历左右的子元素的measure方法. 虽然ViewGroup提供了measureChildren方法遍历每个子元素进行measure, 但是不同的布局类型有不同的measure逻辑, 有的ViewGroup自身尺寸依赖子元素的尺寸(如LinearLayout), 有的部分依赖子元素尺寸(如ScrollView), 因此需要子类实现onMeasure具体过程.
measureChildren方法:
measureChild方法:
measureChildWithMargins方法:
虽然不同ViewGroup的measure流程不一致, 但是measure单个子View的逻辑基本是一样的, 就是上面的measureChildWidthMargins方法, 因此ViewGroup子类基本都使用此方法来measure子元素.
以上几个方法都会调用getChildMeasureSpec()方法:
补充 MeasureSpec.makeMeasureSpec(resultSize, resultMode),也可以看上一篇
Android View框架总结(三)View工作原理
从这个逻辑,我们可以知道child的specMode,specSize是通过其父View提供的MeasureSpec参数得到specMode和specSize,然后根据计算出来的specMode以及子View的childDimension(layout_width或layout_height)来计算自身的measureSpec,如果其本身包含子视图,则计算出来的measureSpec将作为调用其子视图measure函数的参数,同时也作为自身调用setMeasuredDimension的参数,如果其不包含子视图则默认情况下最终会调用onMeasure的默认实现,并最终调用到setMeasuredDimension。
FrameLayout的measure过程
上面方法总结如下:
- 如果传入的SpecMode是EXACTLY, FrameLayout自身的尺寸不依赖子元素, 或者子元素是wrap_content(有AT_MOST限制), 那么一次遍历即可完成, 子元素兄弟之间没有依赖关系, 都是调用measureChildWidthMargins即可;
- 否则需要遍历子元素measure后, 取最大的尺寸(但不超过父容器限制)为自身尺寸, 然后重新measure那些宽或高是match_parent的子元素, 再次遍历过程中SpecMode变成了EXACTLY.
第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。
如果你觉得好,随手点赞,也是对笔者的肯定,也可以分享此公众号给你更多的人,原创不易
Android View框架总结(四)View布局流程之Measure的更多相关文章
- Android View框架总结(五)View布局流程之Layout
转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52216195 View树的Layout流程 View的Layout时序图 View布局 ...
- Android学习笔记_3_四种布局
Android布局是应用界面开发的重要一环,在Android中,共有四种布局方式, 分别是:FrameLayout( 帧布局 ).LinearLayout (线性布局).TableLayout(表格布 ...
- Android View框架总结(六)View布局流程之Draw过程
请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52236145 View的Draw时序图 ViewRootImpl.p ...
- Android艺术探索第四 view的自定义
一.初见View View的层级关系(Veiw到底分成几层,自定义view是从那一层开始绘制的) R:Veiw树的结构如下 ,自定义View是从DecorView开始的;DecorView是View树 ...
- Android应用层View绘制流程之measure,layout,draw三步曲
概述 上一篇博文对DecorView和ViewRootImpl的关系进行了剖析,这篇文章主要是来剖析View绘制的三个基本流程:measure,layout,draw.仅仅有把这三个基本流程搞清楚了, ...
- Android显示框架:自定义View实践之绘制篇
文章目录 一 View 二 Paint 2.1 颜色处理 2.2 文字处理 2.3 特殊处理 三 Canvas 3.1 界面绘制 3.2 范围裁切 3.3 集合变换 四 Path 4.1 添加图形 4 ...
- Android View 的绘制流程之 Layout 和 Draw 过程详解 (二)
View 的绘制系列文章: Android View 的绘制流程之 Measure 过程详解 (一) Android View 绘制流程之 DecorView 与 ViewRootImpl 在上一篇 ...
- View学习(四)-View的绘制(draw)过程
View的draw过程相比之于measrue过程,也是比较简单的.并且在我们自定义View时,也经常需要重写onDraw方法,来绘制出我们要实现的效果. 如之前的文章所说,绘制的流程也是起始于View ...
- Android 应用框架 —— 组件
本文内容根据个人自学整理记录,理解不当之处,希望大家批评指正,大家相互学习,写学习归纳,写博客是个好习惯,希望能够坚持下去. 在前一篇文章当中介绍了Android 的系统框架,主要是为了让大家对And ...
随机推荐
- [HNOI2014]画框
题目描述 小T准备在家里摆放几幅画,为此他买来了N幅画和N个画框.为了体现他的品味,小T希望能合理地搭配画与画框,使得其显得既不过于平庸也不太违和. 对于第 幅画与第 个画框的配对,小T都给出了这个配 ...
- LOJ #6119. 「2017 山东二轮集训 Day7」国王
Description 在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 exciting 的,当且仅当 ...
- ●BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3926题解&&代码: 后缀自动机,Trie树 如果以每个叶子为根,所有的子串一 ...
- [bzoj4162]shlw loves matrix II
来自FallDream的博客,未经允许,请勿转载,谢谢 给定矩阵k*k的矩阵M,请计算 M^n,并将其中每一个元素对 1000000007 取模输出. k<=50 n<=2^10000 考 ...
- [51nod1238]最小公倍数之和V3
来自FallDream的博客,未经允许,请勿转载,谢谢. ----------------------------------------------------------------------- ...
- 学生管理系统(SSM简易版)总结
之前用 Servlet + JSP 实现了一个简易版的学生管理系统,在学习了 SSM 框架之后,我们来对之前写过的项目重构一下! 技术准备 为了完成这个项目,需要掌握如下技术: Java 基础知识 前 ...
- kindeditor配合requirejs使用时,ready失效
KindEditor官方的文档在使用KindEditor时是这样的: KindEditor.ready(function(K)) { K.create('#editor_id'); } 使用了自己提供 ...
- Linux的哲学思想
1.一切皆文件:2.单一目的的小程序:3.组合小程序完成复杂任务:4.文本文件保存配置信息:5.尽量避免捕获用户接口:6.提供机制,而非策略. 说到底Linux的哲学思想在于方便和更好的管理后台,不同 ...
- 列表ListBox、ListView、GridView 排序
列表排序 1.使用控件默认排序方式(推荐) ListControl.Items.SortDescriptions.Clear(); ListControl.Items.SortDescriptions ...
- Ubuntu14.04和Windows双系统时无法挂载磁盘解决方法
基本状况:我电脑Ubuntu14.04 和 Windows10 双系统,一个固态磁盘,一个机械磁盘.Ubuntu14.04装固态里面了,固态里没有Windows内容. 问题:Ubuntu14.04系统 ...