1、画图(http://www.jianshu.com/p/060b5f68da79),结合艺术探索的总结、Hierarchy View的展示
解释下各层的意思,注意最后讲下ViewRoot--ViewRootImpl类,图中并没有展示
2、三大过程
总体说:measure、layout、draw
measure过程决定了View的宽高,可以通过getMeasuredWith和getMeasuredHeight来获取View测量后的宽高
layout过程决定了View四个顶点的坐标和实际的View的宽高,可以通过getTop、getBottom、getLeft、getRight来得到四个点坐标,getWith、getHeight来得到宽高
draw过程是将View的内容呈现到屏幕上
1、measure(最复杂的过程)
1、MeasureSpec类
1、测量规格,分为widthMeasureSpec、heightMeasureSpec,这个值确定View的宽高非常重要
2、一个32位int值,高2位代表测量模式SpecMode、低30位代表规格大小SpecSize,然后介绍下两种主要的测量模式和其对应的值
3、View的MeasureSpec由自身的布局参数LayoutParams和父容器的MeasureSpec共同决定的
2、View的measure过程
1、调用onMeasure(int widthMeasureSpec, int heightMeasureSpec)
其中的widthMeasureSpec和heightMeasureSpec就是由View的LayoutParams和父容器的MeasureSpec共同决定的,然后传入到这个函数里
2、setMeasuredDimension(int ,int )就是最终设置View的测量宽高
3、view默认的AT_MOST和EXACTLY模式作同样的处理,所以view要重写onMeasure函数对AT_MOST作另外处理,给它一个默认值
从而实现对wrap_content的支持
3、ViewGroup的measure过程
1、除了完成自己的measure过程,还通过measureChildren遍历调用所有子View的measure方法
(查看measureChildren方法中的measureChild方法可以看到,子view的MeasureSpec是由父容器的MeasureSpc和自身的LayoutParams,还有padding决定的)
2、ViewGroup是抽象类,没有实现自己的onMeasure()函数,而是由各个具体子类去实现,如LinearLayout、RelativeLayout
4、获取View的宽高
1、View的measure过程和Activity生命周期不是同步的,所以在OnCreate、OnStart、OnResume中均无法获取
2、简单使用的方法是,view.post(runnable),int width = view.getWidth()(布局后的实际宽度);
通过post将一个runnable投递到消息队列的尾部
2、layout
1、layout方法中调用setFrame(l, t, r, b)函数可以确定view本身的位置
2、layout方法中调用onLayout来确定子View的位置
3、getMeasureWidth和getWidth的关系,一个是测量值,一个是最终值(通过四个点坐标来计算),一般来讲这两个值是一样的
3、draw
1、主要有四个过程(一共有六个)
1、绘制背景
drawBackground(canvas);
2、绘制自己
onDraw(canvas)
重点,通常重写此方法
3、绘制子View
dispatchDraw(canvas)
4、绘制装饰
(绘制边框,比如scrollbars,其实每一个view,比如TextView也是有滚动条的,只是设置的显示或者不显示,或者gone)
2、View的onDraw()函数默认为空,由继承它的子类去实现
3、Canvas和Paint
1、Canvas,可以理解为画布,可以画圆、画矩形、画弧、画线、写字等,有很多函数。
2、Paint,可以理解为画笔,可以设置颜色、风格等。
4、设置对padding的支持
4、从以上的总结来推测一下什么情况下影响UI效率
1、measure过程主要受子view个数影响?
另外非常值得注意的是,RelativeLayout会进行两次测量,LinearLayout中使用layout_weight会进行两次测量
2、layout过程主要受布局嵌套深度影响?
减少嵌套深度是优化布局非常重要的一个点(层次深的话会多调用onLayout函数,onLayout函数一般会比较复杂,而setFrame本身并不复杂)
3、draw过程
四个过程都可能影响绘制时间,比如背景图片太大等