zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    java 的 线程池应用和实践
    拦截信息短信息并转发到指定手机
    分享 UC优视 的android程序员面试题
    解释通讯协议中的xml
    设计模式工厂模式
    MongoDB基础教程系列第一篇 进入MongoDB世界
    Docx组件读写Word文档介绍
    [转]Oracle数据库逻辑增量备份之exp/imp
    JSON文件读取
    JAVA综合--如何掌握JDK1.5枚举类型[转]
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4508007.html
Copyright © 2011-2022 走看看