【Android View绘制之旅】Layout过程
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过程相关推荐
- 【Android View绘制之旅】Draw过程
出效果:绘制 经过前面的准备工作 :[Android View绘制之旅]Measure过程,[Android View绘制之旅]Layout过程 我们的视图具备了宽高数据,位置数据,现在到了激动人心的 ...
- 【Android View绘制之旅】主脉络
没搞清楚View绘制原理会怎么样? 只会玩玩初级的组件 看不懂哪些绚丽效果组件实现的原理,即使你有源码 PM会对你很失望,因为有点高级特性你就跪了 当然好的工作机会是没有你的份的 View绘制之旅该怎 ...
- Android View绘制之旅
1.说在起点的话 很早前就想将View绘制原理这块给搞清楚搞透彻,但是奈何自己无知还是愚钝,总未能得真经,所以此次决意好好出发,做到有始有终. 我分析了一下自己的问题,自己实在太功利了,总希望看一两篇 ...
- 【Android View绘制之旅】Measure过程
1.为什么要进行Measure? 替人做了原本应该做的工作.在写xml的时候,布局参数如 wrap_content,match_parent,weight 等等给我们开发界面的时候带来方便,但是机器可 ...
- android view绘制过程
应用程序窗口内部所包含的视图对象的实际类型为DecorView.DecorView类继承了View类,是作为容器(ViewGroup)来使用的,它的实现如图1所示: 每一个应用程序窗口的视图对象都有一 ...
- android view 绘制过程,深入理解Android中View绘制的三大流程
前言 最近对Android中View的绘制机制有了一些新的认识,所以想记录下来并分享给大家.View的工作流程主要是指measure.layout.draw这三大流程,即测量.布局和绘制,其中meas ...
- android 绘图流程,Android View绘制流程
前言 不知道大家有没有想过一个问题,当启动一个Activity的时候,相应的XML布局文件中的View是如何显示到屏幕上的?有些同学会说是通过onMeasure().onLayout().onDraw ...
- Android View 绘制流程
前面讲到 Android View 加载流程,使用 LayoutInflater 将 xml 文件转变成 View ,但是还需要将 View 绘制出来,才能被用户看到,这一过程为绘制流程.由于 And ...
- Android View绘制原理解析
概述 本篇文章主要讲述View是如何在Android源码中产生的,以便于我们能够更好的去自定义一些控件,大体上是按照View绘制的流程来走步骤,在追踪源码之前我们先了解几个基础知识.来看下面的这张图: ...
最新文章
- 14 集成测试方法之自底向上集成方法
- SOA改变的企业软件生态
- Metasploit advanced命令使用技巧
- 怎么强制限制div宽度
- 【Android 应用开发】Canvas 精准绘制文字 ( 测量文本真实边界 | 将文本中心点与给定中心点对齐 )
- npm 安装依赖遇到的问题
- 在线编码工具_我希望在开始编码时就已经知道的工具
- POJ 2031 Building a Space Station
- 三级网络技术_中小型网络系统总体规划与设计方法
- matlab 数组名含变量,求助:如何将带有符号变量的运算结果储存到数组中
- 《Managed DirectX +C# 开发(入门篇)》系列文章
- 01-HTML基础与进阶-day4-录像250
- 既然Java反射可以访问和修改私有成员变量,那封装成private还有什么意义
- a letter and a number
- mes管理系统php原码,MES系统_MES车间管理系统_轻量化定制方案
- 你身边长期不上班的人,靠什么活着?
- 【对比Java学Kotlin】代理
- 爱因斯坦:三篇著名演讲
- 极客日报:iPhone 13或有8款配色;vivo百万年薪招工程师;特斯拉新增行车记录视频紧急情况自动保存功能
- 绩效考核成绩管理平台
热门文章
- Tomcat下HTTPS双向认证配置以及客户端调用案例
- Log4J xml配置
- iframe 父页面与子页面之间的方法的相互调用
- MySQL 使用SELECT ... FOR UPDATE 做事务写入前的确认(转)
- 我的Android进阶之旅------Java字符串格式化方法String.format()格式化float型时小数点变成逗号问题...
- ant读书之使用ant进行java开发--第二章
- cf1139D. Steps to One(dp)
- UltraIso-写入硬盘映像
- Java复制目录/子目录/文件
- python学习日记-2