1. 程式人生 > >Android 獲取控制元件的寬和高

Android 獲取控制元件的寬和高

我們都知道在onCreate()裡面獲取控制元件的高度是0,這是為什麼呢?我們來看一下示例:

首先我們自己寫一個控制元件,這個控制元件非常簡單:

  1. publicclass MyImageView extends ImageView {  
  2.     public MyImageView(Context context, AttributeSet attrs) {  
  3.         super(context, attrs);  
  4.     }  
  5.     public MyImageView(Context context) {  
  6.         super(context);  
  7.     }  
  8.     @Override
  9.     protectedvoid onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  10.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  11.         System.out.println("onMeasure 我被呼叫了"+System.currentTimeMillis());  
  12.     }  
  13.     @Override
  14.     protectedvoid onDraw(Canvas canvas) {  
  15.         super
    .onDraw(canvas);  
  16.         System.out.println("onDraw 我被呼叫了"+System.currentTimeMillis());  
  17.     }  
  18. }  
佈局檔案:
  1. <com.test.MyImageView  
  2.     android:id="@+id/imageview"
  3.     android:layout_width="wrap_content"
  4.     android:layout_height="wrap_content"
  5.     android:src="@drawable/test" />  

測試的Activity的onCreate():
  1. @Override
  2. publicvoid onCreate(Bundle savedInstanceState) {  
  3.     super.onCreate(savedInstanceState);  
  4.     setContentView(R.layout.main);          
  5.     System.out.println("執行完畢.."+System.currentTimeMillis());  
  6. }  
現在我們現在來看一下結果:


說明等onCreate方法執行完了,我們定義的控制元件才會被度量(measure),所以我們在onCreate方法裡面通過view.getHeight()獲取控制元件的高度或者寬度肯定是0,因為它自己還沒有被度量,也就是說他自己都不知道自己有多高,而你這時候去獲取它的尺寸,肯定是不行的.

現在碰到這個問題我們不能不解決,在網上找到了如下辦法:

  1. //------------------------------------------------方法一
  2. int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);  
  3. int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);  
  4. imageView.measure(w, h);  
  5. int height =imageView.getMeasuredHeight();  
  6. int width =imageView.getMeasuredWidth();  
  7. textView.append("\n"+height+","+width);  
  8. //-----------------------------------------------方法二
  9. ViewTreeObserver vto = imageView.getViewTreeObserver();  
  10. vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {  
  11.     publicboolean onPreDraw() {  
  12.         int height = imageView.getMeasuredHeight();  
  13.         int width = imageView.getMeasuredWidth();  
  14.         textView.append("\n"+height+","+width);  
  15.         returntrue;  
  16.     }  
  17. });  
  18. //-----------------------------------------------方法三   
  19. ViewTreeObserver vto2 = imageView.getViewTreeObserver();    
  20. vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {  
  21.     @Override
  22.     publicvoid onGlobalLayout() {  
  23.         imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);    
  24.         textView.append("\n\n"+imageView.getHeight()+","+imageView.getWidth());  
  25.     }    
  26. });    

這三個方法是哪裡找到現在已經忘了.

現在要討論的是當我們需要時候使用哪個方法呢?

現在把測試的Activity改成如下:

  1. @Override
  2.   publicvoid onCreate(Bundle savedInstanceState) {  
  3.       super.onCreate(savedInstanceState);  
  4.       setContentView(R.layout.main);  
  5.       final ImageView imageView = (ImageView) findViewById(R.id.imageview);        
  6.       //------------------------------------------------方法一
  7.       int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);  
  8.       int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);  
  9.       imageView.measure(w, h);  
  10.       int height =imageView.getMeasuredHeight();  
  11.       int width =imageView.getMeasuredWidth();  
  12.       textView.append("\n"+height+","+width);  
  13.       System.out.println("執行完畢.."+System.currentTimeMillis());  
  14.   }  


接著來看下面幾種方式輸出結果:

把測試Activity改成如下:

  1. @Override
  2. publicvoid onCreate(Bundle savedInstanceState) {  
  3.     super.onCreate(savedInstanceState);  
  4.     setContentView(R.layout.main);  
  5.     final ImageView imageView = (ImageView) findViewById(R.id.imageview);  
  6. -----------------------------------------------方法二  
  7.     ViewTreeObserver vto = imageView.getViewTreeObserver();  
  8.     vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {  
  9.         publicboolean onPreDraw() {  
  10.             int height = imageView.getMeasuredHeight();  
  11.             int width = imageView.getMeasuredWidth();  
  12.             textView.append("\n"+height+","+width);  
  13.             returntrue;  
  14.         }  
  15.     });  
  16. }  

結果如下:


方法三就不再測試了同方法二!!!

那麼方法而和方法三在執行上有什麼區別呢?

我們在佈局檔案中加入一個TextView來記錄這個控制元件的寬高.

  1. <ScrollView  
  2.     android:layout_width="wrap_content"
  3.     android:layout_height="wrap_content" >  
  4.     <TextView  
  5.         android:id="@+id/text"
  6.         android:layout_width="wrap_content"
  7.         android:layout_height="wrap_content" />  
  8. </ScrollView>  

先來測試方法而:
  1. @Override
  2. publicvoid onCreate(Bundle savedInstanceState) {  
  3.     super.onCreate(savedInstanceState);  
  4.     setContentView(R.layout.main);  
  5.     final ImageView imageView = (ImageView) findViewById(R.id.imageview);  
  6. -----------------------------------------------方法二  
  7.     ViewTreeObserver vto = imageView.getViewTreeObserver();  
  8.     vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {  
  9.         publicboolean onPreDraw() {  
  10.             int height = imageView.getMeasuredHeight();  
  11.             int width = imageView.getMeasuredWidth();  
  12.             textView.append("\n"+height+","+width);  
  13.             returntrue;  
  14.         }  
  15.     });  
  16. }  

結果如下:


我們再來測試方法三

  1. @Override
  2. publicvoid onCreate(Bundle savedInstanceState) {  
  3.     super.onCreate(savedInstanceState);  
  4.     setContentView(R.layout.main);  
  5.     final ImageView imageView = (ImageView) findViewById(R.id.imageview);  
  6.     //-----------------------------------------------方法三   
  7.     ViewTreeObserver vto2 = imageView.getViewTreeObserver();    
  8.     vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {  
  9.         @Override
  10.         publicvoid onGlobalLayout() {  
  11.             imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);    
  12.             textView.append("\n\n"+imageView.getHeight()+","+imageView.getWidth());  
  13.         }    
  14.     });    
  15. }  

輸出結果如下:


我想這方法二和方法三之間的區別就不用說了吧.

 總結:那麼需要獲取控制元件的寬高該用那個方法呢?

方法一: 比其他