1.为什么要进行Layout?

在【Android View绘制之旅】View之测量Measure过程后,View我们得到View的宽高,但光只有宽高值是不足以反映视图的,更需要知道View所在的位置。

Layout第一步:layout()方法

在【Android View绘制之旅】View之测量Measure里也说过,我们的视图树就是从线性布局开始的,所以我们仍旧是从LinearLayout研究起。
同measure一样,LinearLayout没有覆写layout方法,那么直接就看View的。
虽然View的layout方法没有加final,但是明确禁止覆写。

Derived classes should not override this method. Derived classes with children should override onLayout. In that method, they should call layout on each of their children.

layout方法的入参

入参由当前View的父组件计算得来的,具体见下面的分析。

代码中主要值得关注的地方有如下两处:

设置自身位置并判断位置同上次有无变化 见代码块A

setFrame() :layout结果执行的关键一步

  • 判断一下跟Parent View的相对位置有没有发生变化
  • 判断一下宽高有没有变化sizeChanged,有变化则invalidate一下(到后面draw部分可以探究)
  • 将新的位置值赋值给当前View。

了解View布局的关键结果:mLeft,mRight,mTop,mBottom

拿mLeft来说,他是自身左边到父View的左边的距离,以像素为单位。

The distance in pixels from the left edge of this view’s parent to the left edge of this view.


他们都是距离上边和左边的距离

位置同上次有变化,则执行onLayout 见代码块B

View的onLayout的实现为空,自身位置的设置已经在上面setFrame做过了,在onLayout里一般在当前View内嵌有子View的时候去遍历所有子View并逐一调用他们的layout方法。

线性布局的onLayout()方法

仍旧以代表性的layoutVertical为例子深入分析,
几个局部变量的意义
* majorGravity:线性布局垂直方向上的gravity设置
* minorGravity:线性布局水平方向上的gravity设置
* mTotalLength:分割线高度+ 子组件高度并包含自身上下Margin + 线性布局自身上下padding.

几个主要过程(layout()方法入参是如何计算出来的?在这里能找到答案):

childTop的求解

需要考虑靠上或下或居中的情况。

我们在说到是靠上 靠下 还是居中是有个前提的,就是线性布局除了容纳子组件外还有富余的空间。

富余的空间= bottom - top - mTotalLength

靠上 靠下 还是居中都是如何”处理”这些富余空间的策略而已。拿Gravity.BOTTOM来说吧:其实就是将富余空间放到上边,那么从垂直方向来说,子组件是从mPaddingTop + bottom - top - mTotalLength 开始的,(当然我们还要包括线性布局自身上部的padding.)

childLeft的求解

需要考虑靠上或下或居中的情况。

几个局部变量的意义
* width:当前线性布局的宽度
* childSpace:线性布局横向上除去padding后留给子组件的可用空间

问题:childLeft是子组件左侧到父组件左边的距离,那childLeft包含其自身的leftMargin吗?
拿左侧对齐的代码来说:

childLeft = paddingLeft + lp.leftMargin;

理解如下图:

一目了然,childLeft是不包含其自身的leftMargin,那么其他的如Top,Right类似。
childLeft的求解比较好理解就不多言了。有了上边及左边的位置,childBottom,childRight底部 和右边的位置就唾手可得了。

private void setChildFrame(View child, int left, int top, int width, int height) {        child.layout(left, top, left + width, top + height);
}

View的getMeasureWidth/Height和getWidth/Height的区别是?

说了这么多,Layout的结果是什么?

mLeft
mTop
mRight
mBottom
拥有了更新的值,这个确定了后,相对于其在父组件中的相对位置就确定了,再不停的向外延伸考虑,相对再相对,这个值确定的意义就在于其在整个视图中的绝对位置被确定了。

【Android View绘制之旅】Layout过程相关推荐

  1. 【Android View绘制之旅】Draw过程

    出效果:绘制 经过前面的准备工作 :[Android View绘制之旅]Measure过程,[Android View绘制之旅]Layout过程 我们的视图具备了宽高数据,位置数据,现在到了激动人心的 ...

  2. 【Android View绘制之旅】主脉络

    没搞清楚View绘制原理会怎么样? 只会玩玩初级的组件 看不懂哪些绚丽效果组件实现的原理,即使你有源码 PM会对你很失望,因为有点高级特性你就跪了 当然好的工作机会是没有你的份的 View绘制之旅该怎 ...

  3. Android View绘制之旅

    1.说在起点的话 很早前就想将View绘制原理这块给搞清楚搞透彻,但是奈何自己无知还是愚钝,总未能得真经,所以此次决意好好出发,做到有始有终. 我分析了一下自己的问题,自己实在太功利了,总希望看一两篇 ...

  4. 【Android View绘制之旅】Measure过程

    1.为什么要进行Measure? 替人做了原本应该做的工作.在写xml的时候,布局参数如 wrap_content,match_parent,weight 等等给我们开发界面的时候带来方便,但是机器可 ...

  5. android view绘制过程

    应用程序窗口内部所包含的视图对象的实际类型为DecorView.DecorView类继承了View类,是作为容器(ViewGroup)来使用的,它的实现如图1所示: 每一个应用程序窗口的视图对象都有一 ...

  6. android view 绘制过程,深入理解Android中View绘制的三大流程

    前言 最近对Android中View的绘制机制有了一些新的认识,所以想记录下来并分享给大家.View的工作流程主要是指measure.layout.draw这三大流程,即测量.布局和绘制,其中meas ...

  7. android 绘图流程,Android View绘制流程

    前言 不知道大家有没有想过一个问题,当启动一个Activity的时候,相应的XML布局文件中的View是如何显示到屏幕上的?有些同学会说是通过onMeasure().onLayout().onDraw ...

  8. Android View 绘制流程

    前面讲到 Android View 加载流程,使用 LayoutInflater 将 xml 文件转变成 View ,但是还需要将 View 绘制出来,才能被用户看到,这一过程为绘制流程.由于 And ...

  9. Android View绘制原理解析

    概述 本篇文章主要讲述View是如何在Android源码中产生的,以便于我们能够更好的去自定义一些控件,大体上是按照View绘制的流程来走步骤,在追踪源码之前我们先了解几个基础知识.来看下面的这张图: ...

最新文章

  1. 14 集成测试方法之自底向上集成方法
  2. SOA改变的企业软件生态
  3. Metasploit advanced命令使用技巧
  4. 怎么强制限制div宽度
  5. 【Android 应用开发】Canvas 精准绘制文字 ( 测量文本真实边界 | 将文本中心点与给定中心点对齐 )
  6. npm 安装依赖遇到的问题
  7. 在线编码工具_我希望在开始编码时就已经知道的工具
  8. POJ 2031 Building a Space Station
  9. 三级网络技术_中小型网络系统总体规划与设计方法
  10. matlab 数组名含变量,求助:如何将带有符号变量的运算结果储存到数组中
  11. 《Managed DirectX +C# 开发(入门篇)》系列文章
  12. 01-HTML基础与进阶-day4-录像250
  13. 既然Java反射可以访问和修改私有成员变量,那封装成private还有什么意义
  14. a letter and a number
  15. mes管理系统php原码,MES系统_MES车间管理系统_轻量化定制方案
  16. 你身边长期不上班的人,靠什么活着?
  17. 【对比Java学Kotlin】代理
  18. 爱因斯坦:三篇著名演讲
  19. 极客日报:iPhone 13或有8款配色;vivo百万年薪招工程师;特斯拉新增行车记录视频紧急情况自动保存功能
  20. 绩效考核成绩管理平台

热门文章

  1. Tomcat下HTTPS双向认证配置以及客户端调用案例
  2. Log4J xml配置
  3. iframe 父页面与子页面之间的方法的相互调用
  4. MySQL 使用SELECT ... FOR UPDATE 做事务写入前的确认(转)
  5. 我的Android进阶之旅------Java字符串格式化方法String.format()格式化float型时小数点变成逗号问题...
  6. ant读书之使用ant进行java开发--第二章
  7. cf1139D. Steps to One(dp)
  8. UltraIso-写入硬盘映像
  9. Java复制目录/子目录/文件
  10. python学习日记-2