android 之view的测量和绘制(群英传读书笔记1)

View的测量

android通过onMeasure()方法去测量一个View的大小,在这里面系统给我们提供了一个MeasureSpec的类,我们可以通过他来绘制我们的View,看下源码

MeasureSpec 是一个32位的int值,其中高2位为测量的模式,低30位的胃测量大小,

测量模式(三种):

(1)EXACTLY:精确值模式  给控件设置具体值的时候android:layout_width=“100dp”或者“match_parent”的

(2)AT_MOST :最大值模式 控件为wrap_content的时候,此时控件尺寸随着子控件或者内容变化,但是尺寸不能超过父控件;

(3)UNSPECIFIED :未指明大小的测量模式,View要多大有多大,多在自定义控件使用

注:在onMeasure()方法中只支持EXACTLY模式,所以不重写这个方法时候,只能让View支持Match_parent或者你指定的100dp的数值,像使用wrap_content 就要重写此方法


super.onMeasure(widthMeasureSpec, heightMeasureSpec)点进去可以看到 

android 之view的测量和绘制(群英传读书笔记1)_第1张图片


我们只要把宽和高设置好填进去就可以完成测量工作,所以我们只要在onMeasure()之后把参数设置给 setMeasuredDimension(widthSize , heightSize);方法就可以,

在onMeasure()中,我们调用自定义的MeasureWidth()和MeasureHeight(),来重新定义宽高,参数则是宽和高的MeasureSpec的对象,他的对象包含了测量模式和测量值的大小。

我们以ListView的onMeasure()方法为例来进行介绍下如何自定义测量值:

(1) 从MeasureSpec中拿出具体的的测量模式和大小,代码:

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

(2)通过判断测量的模式,给出不同的测量值。当specMode为EXACTLY时直接指定大小,为其他的模式的时候要给一个默认的大小,尤其是wrap_content的时候,要取出widthSize,或者是heightSize的最小的一个作为最后的测量值,

android 之view的测量和绘制(群英传读书笔记1)_第2张图片

具体的可能还需要我们进去看。。。

下面是模板

android 之view的测量和绘制(群英传读书笔记1)_第3张图片

通过这个我们就可以对宽和高的值去自定义了,

最后可以分三种情况去测试下,

(1)布局中,指定宽和高都是400dp

  (2) 指定宽和高为match_parent,

  (3)使用wrap_content,  (注:这里可以看到我们的view是一个200*200px的一个正方形,因为我们在代码中有设置默认的大小widthMeasureSpec = 200)

View的绘制

在测量好一个View之后,我们就可以去重写onDraw()方法了,在Canvas对象来绘制图像。
 
在onDraw()中有一个参数,就是Canvas对象,在其他的地方,初始化是通过 Canvas mCanvas = new Canvas(bitmap);为什么要使用这个方法,是因为 这样可以将bitmap和Canvas绑定在一起,在onDraw(Canvas canvas)之外调用mCanvas 导致了bitmap发生改变,

ViewGroup的测量:


(1)viewGroup 在测量时通过遍历所有的子View,从而调用子View的measure()获取子View的测量结果,
(2)子view测量完成后,把子view放到合适的位置是view的Layout过程同样ViewGroup在执行Layout时也是遍历所有的子view的Layout,
注:自定义ViewGroup时,通常重写onLayout去控制子view的位置,同样如果要支持wrap_content属性,也要重写onMeasure()方法。


ViewGroup的绘制:

通常不要绘制,因为他没有要绘制的东西,(若不指定背景颜色,onDraw()方法都不会调用),他只是会调用dispatchDraw()方法来绘制子View,过程同样是遍历所有的子view的绘制方法来完成工作。

你可能感兴趣的:(view)