最近在学习自定义view  一遍看一别学顺便记录一下

1.View的测量-------->onMeasure()

     首先,当我们要画一个图形的时候,必须知道三个数据:位置,长度,宽度   才能确定应该在哪个位置画多大的图形。这就是onMeasure方法存在的意义

 

     测量的模式有三种

     1.EXACTLY:             精确模式                    当我们把布局的宽度高度设为指定数值,或者match_parent时系统指定的是这种模式

     2.AT MOST:            最大值模式                  当我们将控件的宽高设为warp_content时,会跟随子控件的大小而变化,系统指定的是这种模式

     3.UNSPECIFIED:      不指定大小测量模式       想多大就多大, 一般用于自定义view

    【view 默认的模式是EXACTLY,当自定义view时,要是不重写onMeasure()方法,控件只会响应设置的具体的宽高或者march_parent,要想使用warp_content,就必须重写onMeasure(),指定warp_content大小】

 2.andoird提供了一个类用来测量view------------>MeasureSpec

     首先:从MeasureSpec对象中获取具体的测量模式和大小:

 

             int mode = MeasureSpec.getMode(heightMeasureSpec);

 

             int size = MeasureSpec.getSize(heightMeasureSpec);

    然后:通过判断测量模式给出不同的测量值:

             当mode为EXACTLY时使用制定的size即可,

            当为其他两种模式的时候需要给它一个默认值,如果指定warp_content属性时,则需要取出我们指定的大小与size中最小的一个来作为测量值

 

demo:

   if(mode == MeasureSpec.EXACTLY){
            height = size;
        }else{
            height = 400;
            if(mode == MeasureSpec.AT_MOST){
                height = Math.min(height,size);
            }
        }

 

举例说明:

     1.自定义一个view  

       public class TouchView extends View {

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

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

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

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

            private int measureHeight(int heightMeasureSpec) {

                  int height = 0;

                  int mode = MeasureSpec.getMode(heightMeasureSpec);

                  int size = MeasureSpec.getSize(heightMeasureSpec);

                  if(mode == MeasureSpec.EXACTLY){  height = size;

                  }else{  height = 400;

                  if(mode == MeasureSpec.AT_MOST){ height = Math.min(height,size); }
             }
                  return height;
           }

             private int measureWidth(int widthMeasureSpec) {

                   int widith = 0;

                   int mode = MeasureSpec.getMode(widthMeasureSpec);

                   int size = MeasureSpec.getSize(widthMeasureSpec);

                   if(mode == MeasureSpec.EXACTLY){widith = size; }else{  widith = 200;

                   if(mode == MeasureSpec.AT_MOST){ widith = Math.min(widith,size);}

                   return widith;         
    }
}       

     2.在xml中使用:

      <com.view.TouchView
        android:layout_height="wrap_content"
        android:background="#f00"
        android:layout_width="wrap_content"
        />

     【可以尝试变换高和宽的属性值来感受下具体的不同】