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效果如下图:

这里写图片描述

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

这里写图片描述

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 哈哈)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值