绘制包括了3个主要步骤
1.Mesure 2.Layout 3.Draw
MesureSpec
32位的整型值 他的高2位表示测量模式 SpecMode 低30位表示某种测量模式下的规格大小SpecSize
三种测量模式
UNSPECIFIED 不指定测量模式 很少使用
EXACTLY 精确测量模式
AT_MOST 最大值模式
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureWidth(widthMeasureSpec),measureHeigth(heightMeasureSpec));
}
//自定义测量宽的方法
private int measureWidth(int widthMeasureSpec) {
int result=0;
int specMode=MeasureSpec.getMode(widthMeasureSpec);
int specSize=MeasureSpec.getSize(widthMeasureSpec);
if (specMode==MeasureSpec.EXACTLY){
result=specSize;
}else{
//自己定义宽度
result=200;
if(specMode==MeasureSpec.AT_MOST){
result=Math.min(result,specSize);
}
}
return result;
}
//自定义测量高的方法
private int measureHeigth(int heightMeasureSpec) {
int result=0;
int specMode=MeasureSpec.getMode(heightMeasureSpec);
int specSize=MeasureSpec.getSize(heightMeasureSpec);
if (specMode==MeasureSpec.EXACTLY){
result=specSize;
}else{
//自己定义宽度
result=200;
if(specMode==MeasureSpec.AT_MOST){
result=Math.min(result,specSize);
}
}
return result;
}
通过以上代码就可以给wrap_content设置一个默认的大小 而不是系统默认的填充整个子View的大小
Measure
计算View的实际大小 回调onMesaure方法
Layout
用来确定View在父容器中的布局位置
Draw
用来将控件绘制出来
最终调用View 的draw方法绘制每个具体的View
第一步:
绘制View背景
drawBackground(canvas);
.....
第二步:
如果需要的话,保存canvas图层,为fading做准备
saveCount=canvas.getSaveCount();
...
canvas.saveLayer(left,top,right,top+length,null,flags);
...
第三步:
绘制View内容
onDraw(canvas);
...
第四步:
绘制View的子view
dispatchDraw(canvas);
...
第五步
如果需要的话 绘制View的fading边缘并恢复图层
canvas.drawRect(left,top,rigth,top+length,p);
...
canvas.restoreToCount(saveCount);
...
第六步
绘制View的装饰(例如滚动条)
onDrawScrollBars(canvas)
ViewGroup的绘制
调用dispatchDraw()方法进行子View的绘制 遍历所有的子View并调用子View的绘制方法来完成绘制工作