Android群英传读书笔记---View测量和绘制

想要写自定义控件,必须清楚控件的绘制原理,幸好,幸好,这本书让我对view的理解更清晰了

View的测量

.1. 我们清楚view的测量是在onMeasure()方法中完成的,测量模式,API提供了三种:

  • EXACTLY:
    精确模式,控件的layout_width,layout_height,为确定值,或者match_parent

  • AT_MOST:
    最大模式,控件的layout_width,layout_height,为wrap_content,此时控件的大小随着控件的子空间或内容改变,但是控件尺寸不能超过父控件允许的最大尺寸。

  • UNSPECIFIED:
    想多大就多大,通常在自定义VIEW时使用

.2. View默认的onMeasure只支持EXACTLY模式,如果不重写onMeasure方法,只能使用EXACTLY模式。控件可以响应指定的具体宽高,或者match_parent,而如果让自定义view支持wrap_content,必须重写onMeasure指定wrap_content时的大小

(新技能get,哈哈哈)

.3. 参看super.onMeasure源码,可知

 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
    }
因此,需要重写measureWidth(int measureWidth)方法:

        @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(measuredWidth(widthMeasureSpec), measuredWidth(heightMeasureSpec));
    }

    private int measuredWidth(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            result = 200;// 给个默认值
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);// 不能超过父控件的最大允许尺寸
            }
        }

        return result;
    }

设置layout_height,layout_width为wrap_content效果如下图:

Android群英传读书笔记---View测量和绘制_第1张图片

设置layout_height=500dp,layout_width=match_parent,效果如下图:

Android群英传读书笔记---View测量和绘制_第2张图片

View的绘制

view测量好之后,就要在onDraw(Canvas canvas)方法上绘制
.1.创建Canvas 对象

Canvas canvas = new Canvas(bitmap)

传进去的bitmap与创建的canvas画布联系在一起,称之为装载画布。这个bitmap用来存储所有绘制在canvas上的像素信息,后面调用的canvas.drawxxx都作用在这个bitmap上。下面的代码可以证实canvas与bitmap的直接关系

canvas.drawBitmap(bitmap1,0,0,null);
Canvas mcanvas = new Canvas(bitmap1);
mcanvas.drawxxx

通过这个mcanvas将绘制效果作用在bitmap1上,在刷新view的时候,就会发现通过onDraw方法绘制出来的bitmap1已经发生了变化,这就是bitmap1承载了mcanvas上所进行的绘图操作,我们其实并没有绘制在mcanvas画布上,而是通过改变bitmap,然后让view重绘,从而改变之后的bitmap

(又get新技能,o(∩_∩)o 哈哈)

你可能感兴趣的:(View测量)