Android系统调用onMeasure来定义view的大小,很长时间理解不是很透彻,今天花了些时间打日志来理解它。总结如下。

        1. widthMeasureSpec和heightMeasureSpec这两个值是android:layout_width="200dp" android:layout_height="80dp"来定义的,它由两部分构成,可通过int specModeHeight = MeasureSpec.getMode(heightMeasureSpec); int specSizeHeight = MeasureSpec.getSize(heightMeasureSpec)来得到各自的值。

如果android:layout_width="wrap_content"或android:layout_width="fill_parent",哪么得到的specMode为MeasureSpec.AT_MOST,如果为精确的值则为MeasureSpec.EXACTLY。另外,specSize要想得到合适的值需要在Androidmanifest.xml中添加

        2.系统默认的onMeasure调用方法是getDefaultSize来实现,有时候在自定义控件的时候多数采用        

       

        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        setMeasuredDimension(widthSize, heightSize);

            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;    }
          3.onMeasure好像会调用两次,这点我没有到代码中具体跟踪了,如果该view的父view是RelativeLayout,则其父view的onMeasur也要测量一下。我在测试中用的xml为:

<?xml version="1.0" encoding="utf-8"?>

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stub    int specModeHeight = MeasureSpec.getMode(heightMeasureSpec);    int specSizeHeight = MeasureSpec.getSize(heightMeasureSpec);    Log.e("HJJ", "****specModeHeight:" + getModeStr(specModeHeight) + ", specSizeHeight:" + specSizeHeight );    int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);setMeasuredDimension(widthSize, heightSize);}

打印出的结果为:

01-06 12:47:53.170: ERROR/HJJ(5639): ****specModeHeight:AT_MOST, specSizeHeight:71401-06 12:47:53.170: ERROR/HJJ(5639): ****specModeHeight:EXACTLY, specSizeHeight:12001-06 12:47:53.190: ERROR/HJJ(5639): ****specModeHeight:AT_MOST, specSizeHeight:71401-06 12:47:53.190: ERROR/HJJ(5639): ****specModeHeight:EXACTLY, specSizeHeight:120

如果将RelativeLayout换成LinearLayout则为

01-06 12:51:17.980: ERROR/HJJ(5779): ****specModeHeight:EXACTLY, specSizeHeight:12001-06 12:51:18.010: ERROR/HJJ(5779): ****specModeHeight:EXACTLY, specSizeHeight:120





测试用的代码如下:

package com.goso.ui.record;import com.goso.ui.R;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.util.Log;import android.view.View;public class RecordView extends View{    static final float PIVOT_RADIUS = 3.5f;    static final float PIVOT_Y_OFFSET = 10f;    static final float SHADOW_OFFSET = 2.0f;    static final float DROPOFF_STEP = 0.18f;    static final float SURGE_STEP = 0.35f;    static final long  ANIMATION_INTERVAL = 70;        Paint mPaint, mShadow;public RecordView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stubinit(context);}public RecordView(Context context) {super(context);// TODO Auto-generated constructor stubinit(context);}private void init(Context context){   Drawable bg = context.getResources().getDrawable(R.drawable.vumeter);   setBackgroundDrawable(bg);      mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);   mPaint.setColor(Color.WHITE);   mShadow = new Paint(Paint.ANTI_ALIAS_FLAG);   mShadow.setColor(Color.argb(60, 0, 0, 0));}    private String getModeStr(int mode){    String modeStr = null;    switch (mode) {        case MeasureSpec.UNSPECIFIED:        modeStr = "UNSPECIFIED";            break;        case MeasureSpec.AT_MOST:        modeStr = "AT_MOST";        break;        case MeasureSpec.EXACTLY:        modeStr = "EXACTLY";            break;        }    return modeStr;    }    @Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stub//    super.onMeasure(widthMeasureSpec, heightMeasureSpec);    int specModeWidth = MeasureSpec.getMode(widthMeasureSpec);    int specSizeWidth = MeasureSpec.getSize(widthMeasureSpec);    int specModeHeight = MeasureSpec.getMode(heightMeasureSpec);    int specSizeHeight = MeasureSpec.getSize(heightMeasureSpec);    //Log.e("HJJ", "specModeWidth:" + getModeStr(specModeWidth) + ", specSizeWidth:" + specSizeWidth );    Log.e("HJJ", "****specModeHeight:" + getModeStr(specModeHeight) + ", specSizeHeight:" + specSizeHeight );//    Log.e("HJJ", "widthMeasureSpec:" + widthMeasureSpec + ", heightMeasureSpec:" + heightMeasureSpec );//    int widthSize = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);//int heightSize = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);    int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);setMeasuredDimension(widthSize, heightSize);//Log.e("HJJ", "width:" + widthSize + ", height:" + heightSize );}@Overrideprotected void onDraw(Canvas canvas) {// TODO Auto-generated method stubsuper.onDraw(canvas);float w = getWidth();float h = getHeight();float pivotX = w / 2;float pivotY = h - PIVOT_RADIUS - PIVOT_Y_OFFSET;float l = h * 7 / 10;float angle = (float) Math.PI * 1/ 8;float sin = (float) Math.sin(angle);float cos = (float) Math.cos(angle);float x0 = pivotX - l * cos;float y0 = pivotY - l * sin;        canvas.drawLine(x0 + SHADOW_OFFSET, y0 + SHADOW_OFFSET, pivotX + SHADOW_OFFSET, pivotY + SHADOW_OFFSET, mShadow);        canvas.drawCircle(pivotX + SHADOW_OFFSET, pivotY + SHADOW_OFFSET, PIVOT_RADIUS, mShadow);        canvas.drawLine(x0, y0, pivotX, pivotY, mPaint);        canvas.drawCircle(pivotX, pivotY, PIVOT_RADIUS, mPaint);}}

<?xml version="1.0" encoding="utf-8"?>


更多相关文章

  1. 面试题5:椭圆里面有个内切圆,内切圆中有文字
  2. ReactNative 调用Android(安卓)原生(二)——原生组件
  3. Android之十一实现登陆页面分析
  4. Android】获取Mac地址
  5. android webService
  6. android的四大组件及其生命周期
  7. Android(安卓)进阶16:IntentService 使用及源码解析
  8. LinearLayout水平居中控制
  9. Android四大基本组件介绍与生命周期

随机推荐

  1. Android标题栏的各种设置
  2. Android layout属性大全
  3. android操作通讯录的联系人
  4. android > tabHost > 微博布局风格
  5. Android autoLink的注意点
  6. android 程序分享。。
  7. [Android UI] listview 自定义style
  8. Android 之 SeekBar用法介绍
  9. Android 7.1.2(Android N) Android系统启
  10. Android安装