学习View第一步

View的测量:

看完了《android群英传》表示需要写点笔记,不然看了也白看。当然,也借鉴了很多优秀的博客。

在画一个图形前,首先应该告诉它,你在这个画板距左边缘5cm,距上边缘5cm,距右边缘5cm,距下边缘5cm,画一个矩形。同样,在Android绘制View前,也要对View进行测量。即告诉系统该画多大的View,在哪里画。这个过程是在onMeasure()中进行的。通过MeasureSpec类来帮助我们来测量View。为了提高效率,View测量的模式有三种。

第一种EXACTLY,精确模式。当宽高为具体数值,例如android:layout_width="5dp"。或者指定为match_parent属性时。

第二种AT_MOST,最大值模式。当宽高指定为warp_content时,控件大小随着控件的子控件或者内容的变化而变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可。

第三种UNSPECIFIED,不指定大小测量模式。View想多大就多大,通常情况下在绘制自定义View时才会使用。

以下为Demo:

View_Measure.java

package com.example.li.view_my_one;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by li on 2016/5/4.
 */
public class View_Measure extends View {

    public View_Measure(Context context) {
        super(context);
    }

    public View_Measure(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public View_Measure(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
    }

    private int measureWidth(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;
    }

    private int measureHeight(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;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.GRAY);
        int width = getWidth();
        int height = getHeight();

    }
}


查看onMeasure()源代码:
onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
            getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
实际是调用setMeasuredDimension()方法,然后我们再查看getDefaultSize()方法:

 public static int getDefaultSize(int size, int measureSpec) {
        int result = size;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        switch (specMode) {
        case MeasureSpec.UNSPECIFIED:
            result = size;
            break;
        case MeasureSpec.AT_MOST:
        case MeasureSpec.EXACTLY:
            result = specSize;
            break;
        }
        return result;
    }
这时候,它首先判断测量模式,然后根据模式来返回不同的值。因此,我们也可以仿照getDefaultSize方法来做一个获得长宽的方法,这下,View_measure.java文件更加懂了吧。

接下来就是布局文件:

<com.example.li.heros_chapter3.View.View_2
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />
也可以将宽高指定为精确值,match_parent,wrap_content这些来看看效果





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值