View绘制

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过程

四个过程都可能影响绘制时间,比如背景图片太大等

你可能感兴趣的:(View绘制)