• View树的measure流程
  • View的measures时序图
  • View布局流程之measure
    • measure过程

      • View的measure过程
      • ViewGroup的measure过程
      • FrameLayout的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的更多相关文章

  1. Android View框架总结(五)View布局流程之Layout

    转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52216195 View树的Layout流程 View的Layout时序图 View布局 ...

  2. Android学习笔记_3_四种布局

    Android布局是应用界面开发的重要一环,在Android中,共有四种布局方式, 分别是:FrameLayout( 帧布局 ).LinearLayout (线性布局).TableLayout(表格布 ...

  3. Android View框架总结(六)View布局流程之Draw过程

    请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52236145 View的Draw时序图 ViewRootImpl.p ...

  4. Android艺术探索第四 view的自定义

    一.初见View View的层级关系(Veiw到底分成几层,自定义view是从那一层开始绘制的) R:Veiw树的结构如下 ,自定义View是从DecorView开始的;DecorView是View树 ...

  5. Android应用层View绘制流程之measure,layout,draw三步曲

    概述 上一篇博文对DecorView和ViewRootImpl的关系进行了剖析,这篇文章主要是来剖析View绘制的三个基本流程:measure,layout,draw.仅仅有把这三个基本流程搞清楚了, ...

  6. Android显示框架:自定义View实践之绘制篇

    文章目录 一 View 二 Paint 2.1 颜色处理 2.2 文字处理 2.3 特殊处理 三 Canvas 3.1 界面绘制 3.2 范围裁切 3.3 集合变换 四 Path 4.1 添加图形 4 ...

  7. Android View 的绘制流程之 Layout 和 Draw 过程详解 (二)

    View 的绘制系列文章: Android View 的绘制流程之 Measure 过程详解 (一) Android View 绘制流程之 DecorView 与 ViewRootImpl 在上一篇  ...

  8. View学习(四)-View的绘制(draw)过程

    View的draw过程相比之于measrue过程,也是比较简单的.并且在我们自定义View时,也经常需要重写onDraw方法,来绘制出我们要实现的效果. 如之前的文章所说,绘制的流程也是起始于View ...

  9. Android 应用框架 —— 组件

    本文内容根据个人自学整理记录,理解不当之处,希望大家批评指正,大家相互学习,写学习归纳,写博客是个好习惯,希望能够坚持下去. 在前一篇文章当中介绍了Android 的系统框架,主要是为了让大家对And ...

随机推荐

  1. [HNOI2014]画框

    题目描述 小T准备在家里摆放几幅画,为此他买来了N幅画和N个画框.为了体现他的品味,小T希望能合理地搭配画与画框,使得其显得既不过于平庸也不太违和. 对于第 幅画与第 个画框的配对,小T都给出了这个配 ...

  2. LOJ #6119. 「2017 山东二轮集训 Day7」国王

    Description 在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 exciting 的,当且仅当 ...

  3. ●BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3926题解&&代码: 后缀自动机,Trie树 如果以每个叶子为根,所有的子串一 ...

  4. [bzoj4162]shlw loves matrix II

    来自FallDream的博客,未经允许,请勿转载,谢谢 给定矩阵k*k的矩阵M,请计算 M^n,并将其中每一个元素对 1000000007 取模输出. k<=50 n<=2^10000 考 ...

  5. [51nod1238]最小公倍数之和V3

    来自FallDream的博客,未经允许,请勿转载,谢谢. ----------------------------------------------------------------------- ...

  6. 学生管理系统(SSM简易版)总结

    之前用 Servlet + JSP 实现了一个简易版的学生管理系统,在学习了 SSM 框架之后,我们来对之前写过的项目重构一下! 技术准备 为了完成这个项目,需要掌握如下技术: Java 基础知识 前 ...

  7. kindeditor配合requirejs使用时,ready失效

    KindEditor官方的文档在使用KindEditor时是这样的: KindEditor.ready(function(K)) { K.create('#editor_id'); } 使用了自己提供 ...

  8. Linux的哲学思想

    1.一切皆文件:2.单一目的的小程序:3.组合小程序完成复杂任务:4.文本文件保存配置信息:5.尽量避免捕获用户接口:6.提供机制,而非策略. 说到底Linux的哲学思想在于方便和更好的管理后台,不同 ...

  9. 列表ListBox、ListView、GridView 排序

    列表排序 1.使用控件默认排序方式(推荐) ListControl.Items.SortDescriptions.Clear(); ListControl.Items.SortDescriptions ...

  10. Ubuntu14.04和Windows双系统时无法挂载磁盘解决方法

    基本状况:我电脑Ubuntu14.04 和 Windows10 双系统,一个固态磁盘,一个机械磁盘.Ubuntu14.04装固态里面了,固态里没有Windows内容. 问题:Ubuntu14.04系统 ...