Android UI 绘制过程浅析(三)layout过程
前言
上一篇blog中,了解到measure过程对View进行了测量,得到measuredWidth/measuredHeight。对于ViewGroup,则计算出全部children的宽高进行求和。本篇来分析一下layout过程。
layout综述
layout方法对一个View及它的后代分配size与position,是View绘制过程的第二步(the second phase of layout mechanism),其中用到了上一步measure出的宽高。与measure-onMeasure相似,layout中也是回调了onLayout方法。但有一点不一样,layout并没有被声明为final。
子View在继承后,不应当重写onLayout;当子View是一个ViewGroup时,需要重写onLayout,对该ViewGroup下面的每一个View调用layout。
layout四个参数l, t, r, b分别表示相对于ParentView的距离,最常见的传参就是(0, 0, width, height)。
public void layout(int l, int t, int r, int b) {
if ((mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) != 0) {
onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec);
mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
}
int oldL = mLeft;
int oldT = mTop;
int oldB = mBottom;
int oldR = mRight;
boolean changed = isLayoutModeOptical(mParent) ?
setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b);
if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
onLayout(changed, l, t, r, b);
mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED;
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnLayoutChangeListeners != null) {
ArrayList<OnLayoutChangeListener> listenersCopy =
(ArrayList<OnLayoutChangeListener>)li.mOnLayoutChangeListeners.clone();
int numListeners = listenersCopy.size();
for (int i = 0; i < numListeners; ++i) {
listenersCopy.get(i).onLayoutChange(this, l, t, r, b, oldL, oldT, oldR, oldB);
}
}
}
mPrivateFlags &= ~PFLAG_FORCE_LAYOUT;
mPrivateFlags3 |= PFLAG3_IS_LAID_OUT;
}
layout方法中,首先根据标志位判断是否需要重新measure,随后对是否为optical进行判断,这个参数用来控制投影等效果,通常情况下直接进入setFrame,setFrame判断视图大小是否发生了变化,以确定有没有必要进行重绘。
随后回调onLayout,在View中,onLayout是个空壳,什么都没有做;在ViewGroup中则依次对子View调用layout。
如果layout有变化,则通知所有注册的Listener变化前后的layout数值。
setFrame
当size和position变化时,返回true。如果发生了变化,会在setFrame方法内部调用invalidate。
onLayout
View中onLayout什么都没有做,在ViewGroup中,根据各自实际规则(Linear、Relative 等)对内部Views进行布局安排。
getMeasuredWidth与getWidth
- 可以调用的时机不同:getMeasuredWidth在measure后即可调用,getWidth要在layout后才可以调用。(在发生时机之前调用的话均返回0)
- 含义不同:getMeasuredWidth是View计算出自己的实际大小,getWidth是在布局后的大小。最简单的,在ScrollLayout中,getHeight返回屏幕内的高度,getMeasuredHeight返回屏幕内+屏幕外的总高度。
小结
这一篇比较简单,因为大部分情况下,都不需要重写onLayout方法;一旦重写该方法(ViewGroup),就会发现要做的事情还是很多的,参见LinearLayout.onLayout、RelativeLayout.onLayout。
下一篇着手onDraw()。
Android UI 绘制过程浅析(三)layout过程的更多相关文章
- Android UI 绘制过程浅析(五)自定义View
前言 这已经是Android UI 绘制过程浅析系列文章的第五篇了,不出意外的话也是最后一篇.再次声明一下,这一系列文章,是我在拜读了csdn大牛郭霖的博客文章<带你一步步深入了解View> ...
- Android UI 绘制过程浅析(一)LayoutInflater简介
前言 这篇blog是我在阅读过csdn大牛郭霖的<带你一步步深入了解View>一系列文章后,亲身实践并做出的小结.作为有志向的前端开发工程师,怎么可以不搞懂View绘制的基本原理——简直就 ...
- Android UI 绘制过程浅析(四)draw过程
前言 draw是绘制View三个步骤中的最后一步.同measure.layout一样,通常不对draw本身进行重写,draw内部会调用onDraw方法,子类View需要重写onDraw(Canvas) ...
- Android UI 绘制过程浅析(二)onMeasure过程
前言 View的绘制过程分为 measure.layout.draw三个步骤,接下来对这三个步骤逐一进行研究. measure方法的签名 public final void measure(int w ...
- Android UI绘制流程及原理
一.绘制流程源码路径 1.Activity加载ViewRootImpl ActivityThread.handleResumeActivity() --> WindowManagerImpl.a ...
- 自己定义View Layout过程 - 最易懂的自己定义View原理系列(3)
前言 自己定义View是Android开发人员必须了解的基础 网上有大量关于自己定义View原理的文章.但存在一些问题:内容不全.思路不清晰.无源代码分析.简单问题复杂化等等 今天,我将全面总结自己定 ...
- 自定义View Layout过程 (3)
目录 目录 1. 知识基础 具体请看我写的另外一篇文章:(1)自定义View基础 - 最易懂的自定义View原理系列 2. 作用 计算View视图的位置. 即计算View的四个顶点位置:Left.To ...
- Android UI(一)Layout 背景局部Shape圆角设计
Jeff Lee blog: http://www.cnblogs.com/Alandre/ (泥沙砖瓦浆木匠),retain the url when reproduced ! Thanks ...
- 简单研究Android View绘制一 测量过程
2015-07-27 16:52:58 一.如何通过继承ViewGroup来实现自定义View?首先得搞清楚Android时如何绘制View的,参考Android官方文档:How Android Dr ...
随机推荐
- K2 BPM打造企业新门户,步入移动办公时代
公司介绍步步高教育电子有限公司(前身为步步高电脑电玩厂)是广东步步高电子工业有限公司属下的三个分公司之一,一直致力于面向广大学生的教育电子产品的研发与生产,主要产品有视频学习机.点读机.学生电脑.语言 ...
- js异步加载
默认情况javascript是同步加载的,也就是javascript的加载时阻塞的,后面的元素要等待javascript加载完毕后才能进行再加载,对于一些意义不是很大的javascript,如果放在页 ...
- 在 Apache error_log 中看到多个信息,提示 RSA server certificate CommonName (CN) 与服务器名不匹配(转)
在 Apache error_log 中看到多个信息,提示 RSA server certificate CommonName (CN) 与服务器名不匹配. Article ID: 1500, cre ...
- 视频1-14待JSP课程看完再练习
视频1-14待JSP课程看完再练习 http://www.imooc.com/video/5555
- 获取本地soapUI项目路径
def projectDir = ${projectDir}
- <我是一只IT小小鸟>读书笔记
这篇文章给我感触最深的是开篇蒋宇东所出的一道选择题--今后的发展选择有三条:A.做一辈子IT民工:B.将大学时欠下来的债补上:C.改行. 他们用自己的成长故事告诉师弟师妹们:一定要弄清楚上大学首要的任 ...
- js从后台无法取值问题
前台代码 <script type="text/javascript"> $(function () { var chart; $(document).ready(fu ...
- LintCode Maximum Depth of Binary Tree
1 /** * Definition of TreeNode: * public class TreeNode { * public int val; * public TreeNode left, ...
- LeetCode() Min Stack 不知道哪里不对,留待。
class MinStack { public: MinStack() { coll.resize(2); } void push(int x) { if(index == coll.size()-1 ...
- netmon,messageanalyzer
Microsoft Message Analyzer Operating Guide https://technet.microsoft.com/en-us/library/jj649776.aspx ...