一般情况下,要绘制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"
/>
运行结果如下
其实再复杂的自定义控件都是一步步的整合出来的,相信我们一步一步来肯定能写的出来,加油
1万+

被折叠的 条评论
为什么被折叠?



