android自定义控件 onMeasure() 测量尺寸

上次讲的自定义控件刷新点屏幕的任意地方都会刷新,而且在xml里自定义控件下面放一个textview的话,这个TextView是显示不出来的,不只这个,以前的几个自定义控件都是

为什么呢?今天来讲下onMeasure()

在自定义刷新控件的基础上重写onMeasure方法

根据上一篇自定义组件修改

注释在代码里

 

[html] view plaincopy
 
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:orientation="vertical"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="wrap_content"  
  5.     >  
  6.     <xue.test.CusView3  
  7.         android:id="@+id/cusview3"  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         >  
  11.     </xue.test.CusView3>  
  12.     <TextView  
  13.        android:layout_width="wrap_content"  
  14.        android:layout_height="wrap_content"  
  15.        android:text="我终于出现了" />  
  16. </LinearLayout>  


这里的TextView无法显示,想要显示的话,要测量控件的大小

 

 

[java] view plaincopy
 
  1. public class CusView3 extends View {  
  2.   
  3.     private int color = 0;  
  4.     private String text = "点击我刷新";  
  5.     private Paint mPaint;  
  6.     private int mAscent;  
  7.   
  8.     public CusView3(Context context, AttributeSet attrs) {  
  9.         super(context, attrs);  
  10.         mPaint = new Paint();  
  11.         mPaint.setStyle(Style.FILL);  
  12.         mPaint.setTextSize(35.0f);  
  13.         setPadding(20, 60, 0, 0); //设置padding  
  14.     }  
  15.   
  16.     @Override  
  17.     protected void onDraw(Canvas canvas) {  
  18.         super.onDraw(canvas);  
  19.         if (color > 2) {  
  20.             color = 0;  
  21.         }  
  22.         switch (color) {  
  23.         case 0:  
  24.             mPaint.setColor(Color.GREEN);  
  25.             break;  
  26.         case 1:  
  27.             mPaint.setColor(Color.RED);  
  28.             break;  
  29.         case 2:  
  30.             mPaint.setColor(Color.BLUE);  
  31.             break;  
  32.   
  33.         default:  
  34.             break;  
  35.         }  
  36.   
  37.         canvas.drawText(text, getPaddingLeft(), getPaddingTop(), mPaint);  
  38.     }  
  39.   
  40.     public void changeColor() {  
  41.         color++;  
  42.     }  
  43.   
  44.     /** 
  45.      * 比onDraw先执行 
  46.      *  
  47.      * 一个MeasureSpec封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求。 
  48.      * 一个MeasureSpec由大小和模式组成 
  49.      * 它有三种模式:UNSPECIFIED(未指定),父元素部队自元素施加任何束缚,子元素可以得到任意想要的大小; 
  50.      *              EXACTLY(完全),父元素决定自元素的确切大小,子元素将被限定在给定的边界里而忽略它本身大小; 
  51.      *              AT_MOST(至多),子元素至多达到指定大小的值。 
  52.      *  
  53.      *   它常用的三个函数:    
  54.      * 1.static int getMode(int measureSpec):根据提供的测量值(格式)提取模式(上述三个模式之一) 
  55.      * 2.static int getSize(int measureSpec):根据提供的测量值(格式)提取大小值(这个大小也就是我们通常所说的大小)  
  56.      * 3.static int makeMeasureSpec(int size,int mode):根据提供的大小值和模式创建一个测量值(格式) 
  57.      */  
  58.     @Override  
  59.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  60.         setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));  
  61.     }  
  62.   
  63.     private int measureWidth(int measureSpec) {  
  64.         int result = 0;  
  65.         int specMode = MeasureSpec.getMode(measureSpec);  
  66.         int specSize = MeasureSpec.getSize(measureSpec);  
  67.   
  68.         if (specMode == MeasureSpec.EXACTLY) {  
  69.             // We were told how big to be  
  70.             result = specSize;  
  71.         } else {  
  72.             // Measure the text  
  73.             result = (int) mPaint.measureText(text) + getPaddingLeft() + getPaddingRight();  
  74.             if (specMode == MeasureSpec.AT_MOST) {  
  75.                 // Respect AT_MOST value if that was what is called for by  
  76.                 // measureSpec  
  77.                 result = Math.min(result, specSize);// 60,480  
  78.             }  
  79.         }  
  80.   
  81.         return result;  
  82.     }  
  83.   
  84.     private int measureHeight(int measureSpec) {  
  85.         int result = 0;  
  86.         int specMode = MeasureSpec.getMode(measureSpec);  
  87.         int specSize = MeasureSpec.getSize(measureSpec);  
  88.   
  89.         mAscent = (int) mPaint.ascent();  
  90.         if (specMode == MeasureSpec.EXACTLY) {  
  91.             // We were told how big to be  
  92.             result = specSize;  
  93.         } else {  
  94.             // Measure the text (beware: ascent is a negative number)  
  95.             result = (int) (-mAscent + mPaint.descent()) + getPaddingTop() + getPaddingBottom();  
  96.             if (specMode == MeasureSpec.AT_MOST) {  
  97.                 // Respect AT_MOST value if that was what is called for by  
  98.                 // measureSpec  
  99.                 result = Math.min(result, specSize);  
  100.             }  
  101.         }  
  102.         return result;  
  103.     }  
  104. }  

效果图

 

代码 http://download.csdn.net/detail/ethan_xue/4178423

posted @ 2015-05-16 16:15  brave-sailor  阅读(1133)  评论(0编辑  收藏  举报