View的测量

一般情况下,要绘制View必须要对View进行测量,这个方法就是onMeasure() 

Android 系统给我们提供了一个短小精悍却功能强大的类--------MeasureSpec类,通过它来帮助我们测量View,


MeasureSpec是一个32位的int值,高两位是测量的模式,低30位是测量的大小,在计算中使用位运算的原因是为了提高并优化效率


测量的模式可以为一下三种:

  *EXACTLY

    精确值模式,当我们将控件的layout——widt属性或layout——heig属性指定为具体数值时,系统使用的是EXACTLY模式

  *AT_MOST

   即最大值模式,当控件的layout——widt属性或layout——heig属性指定为wrap——content时,控件大小一般随着控件的子控件或内容的变化而变化,只要不超过父View的尺寸即可

  *UNSPECIFIED

  这个属性不指定大小的测量模式,VIew想多大就多大,通常情况下在绘制自定义View时才会使用。

  View类默认的onMeasure()方法只支持第一个模式,如果在自定义控件的时候不重写onMeasure方法的话。就只能使用第一种模式。控件可以相应你指定的具体宽高值或者是match_parent属性,而如果让自定义View支持wrap——content属性,那么就必须重写onMea方法来指定wrap_content时的大小。


在onMeasure()中, 系统最终会调用setMeasuredDimension(int measuredWidth,int heigMeasureSpec);方法将测量后的宽高值设置进去。所以在重写后,最终要做的工作就是把测量后的宽高值作为参数设置给setMeasuredDimension()方法。

 

代码如下

Demo是自定义的View

public class Demo extends View{


	public Demo(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}
	
	public Demo(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public Demo(Context context, AttributeSet attrs, int defStyleAttr,
			int defStyleRes) {
		super(context, attrs, defStyleAttr, defStyleRes);
		// TODO Auto-generated constructor stub
	}
	

	public Demo(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
		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;
	}
	
	
}

在XML文件中

<com.example.test.Demo
	    android:layout_width="200dp"
	    android:layout_height="200dp"
	    android:background="#223366"
	    />


运行结果如下


其实再复杂的自定义控件都是一步步的整合出来的,相信我们一步一步来肯定能写的出来,加油



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值