您的位置:首页 > 移动开发 > Android开发

Android 自定义View(2)

2016-04-28 23:56 363 查看
一个View要显示在界面上,需要经历一个View树的遍历过程,这个过程又可以分为三个过程,也就是自定义View中的三要素:大小,位置,画什么,即onMesure(),onLayout(),onDraw()。

onMesure()确定一个View的大小;

onLayout()确定View在父节点上的位置;

onDraw()绘制View 的内容;

这个过程的启动是由ViewRoot.performTraversals()函数发起的,子View也可以通过一些方法来请求重新遍历View树,但是在遍历过程View树时并不是所有的View都需要重新测量,布局和绘制,在View树的遍历过程中,系统会判断View是否需要重新绘制,如果需要才会真的去绘制View。

一、onMesure()

这个方法会被View中的measure方法调用,并且传入经过父视图View计算得到的widthMeasureSpec和heightMeasureSpec,即控件的宽和高。这2个参数也将确定控件宽高的规格specMode。调用MeasureSpec.getMode(widthMeasureSpec)将得到specMode:测量模式。specMode有3种类型:

1.EXACTLY

一般是march_parent或者设置了明确大小;

2.AT_MOST

一般为warp_content,表示大小限制在一定值内,最大为父View的大小;

3.UNSPECIFIED

一般较少使用,表示任意大小。

之后,根据得到的类型,设置自己想要的宽高,调用setMeasuredDimension(widthMeasureSpec,heightMeasureSpec)将宽高设定,控件的宽高就确定了。

注:只有在setMeasuredDimension()方法调用后,视图大小才确定,getMeasuredWidth()和getMeasuredHeight()才能得到正确的值。

对于View.onMesure():一般的流程是:

获取测量尺寸和模式,定义临时变量存储结果

判断测量模式: specMode

是EXACTL,就使用测量规格中的尺寸;

是UNSPECIFIED,就使用自身计算的尺寸;

是AT_MOST,就使用自身计算的尺寸与规定尺寸中较小的一个;

最后,设置测量尺寸setMeasuredDimension;

对于ViewGroup.onMesure():这个情况比较多,一般根据具体情况判断怎么设置大小;

二、onLayout()

这个方法一般会在自定义View继承ViewGroup的时候需要重写的方法。

在onLayout()方法之后,getWidth()和getHeight()才能获取到视图的宽高。

三、onDraw()

顾名思义,这是绘制视图的方法。一般流程是:

ViewRoot调用DecorView的draw()方法:ViewRoot–>DecorView.draw(canvas)

- DecorView的draw()方法调用自己的dispatchDraw(Canvas canvas)方法,然后在此方法中会调用子view的draw(Canvas canvas, ViewGroup parent, long drawtime)方法,此方法会调用单个参数的draw(Canvas canvas)方法。

draw的流程:

1. 绘制该View 的背景;

2. 为显示渐变框做一些准备操作 (一般不需要改渐变框);

3. 调用onDraw绘制内容 (ViewGroup不需要实现该方法);

4. 调用dispatchDraw绘制子View ;

onDraw是每个View需要实现的,否则View默认只能显示背景,而实现onDraw就是为了画出View的内容,而ViewGroup一般不需要实现onDraw,因为它仅仅是作为View的容器没有需要绘制东西,

dispatchDraw用来遍历ViewGrop的所有子View,执行draw方法。

最后,系统给了我们多种draw的实现方法,具体暂时不记了。

Canvas画布;

Paint 画笔;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 自定义View