Android进阶笔记18:Android 获取Button的高度、宽度、坐标值


1. 问题

如何获取一个控件的长和高,相信很多朋友第一眼看见这个问题都会觉得很简单,直接在onCreate里面调用getWidth、getMeasuredWidth不就可以获得了吗,但是,事实上是并没有简单的,不信的话,你可以去试一下,在onCreate里面,你是无法获得长宽值的,始终为0

 1 package com.himi.test;  2 
 3 import android.app.Activity;  4 import android.os.Bundle;  5 import android.util.Log;  6 import android.view.ViewTreeObserver;  7 import android.view.ViewTreeObserver.OnGlobalLayoutListener;  8 import android.widget.Button;  9 
10 public class MainActivity extends Activity { 11 
12     private Button button; 13 
14  @Override 15     protected void onCreate(Bundle savedInstanceState) { 16         super.onCreate(savedInstanceState); 17  setContentView(R.layout.activity_main); 18 
19         button = (Button) findViewById(R.id.button); 20         Log.e("Test", "getWidth宽度:" + button.getWidth()); 21         Log.e("Test", "getHeight高度:" + button.getMeasuredWidth()); 22  } 23 
24 }

程序运行结果如下:

 

2. 原因

这是为什么呢,其实熟悉view绘制流程的朋友应该一眼就看出来了,在onCreate中,我们的控件其实还并没有画好,换句话说,等onCreate方法执行完了,我们定义的控件才会被度量(measure),所以我们在onCreate方法里面通过view.getHeight()获取控件的高度或者宽度肯定是0。

 

3. 获取Button的高度、宽度、坐标值:

(1)利用延时(保证onCreate先完成):

 1 package com.himi.test;  2 
 3 import android.app.Activity;  4 import android.os.Bundle;  5 import android.util.Log;  6 import android.view.ViewTreeObserver;  7 import android.view.ViewTreeObserver.OnGlobalLayoutListener;  8 import android.widget.Button;  9 
10 public class MainActivity extends Activity { 11 
12     private Button button; 13 
14  @Override 15     protected void onCreate(Bundle savedInstanceState) { 16         super.onCreate(savedInstanceState); 17  setContentView(R.layout.activity_main); 18 
19         button = (Button) findViewById(R.id.button); 20         Log.e("Test", "getWidth宽度:" + button.getWidth()); 21         Log.e("Test", "getHeight高度:" + button.getMeasuredWidth()); 22 
23         new Thread() { 24 
25  @Override 26             public void run() { 27                 synchronized (this) { 28                     try { 29                         wait(1000);// 1秒
30                     } catch (InterruptedException e) { 31                         // TODO Auto-generated catch block
32  e.printStackTrace(); 33  } 34  } 35 
36                 Log.e("Test", "高度:" + button.getHeight()); 37                 Log.e("Test", "宽度:" + button.getWidth()); 38 
39                 Log.e("Test", "左上角坐标x:" + button.getLeft()); 40                 Log.e("Test", "左上角坐标y:" + button.getTop()); 41 
42                 Log.e("Test", "右下角坐标x:" + button.getRight()); 43                 Log.e("Test", "右下角坐标y:" + button.getBottom()); 44 
45  } 46  }.start(); 47          
48  } 49 
50 }

运行程序如下:

 

(2)自己使用API测量

 

 1 package com.himi.test;  2 
 3 import android.app.Activity;  4 import android.os.Bundle;  5 import android.util.Log;  6 import android.view.View;  7 import android.widget.Button;  8 
 9 public class MainActivity extends Activity { 10 
11     private Button button; 12 
13  @Override 14     protected void onCreate(Bundle savedInstanceState) { 15         super.onCreate(savedInstanceState); 16  setContentView(R.layout.activity_main); 17 
18         button = (Button) findViewById(R.id.button); 19         
20         
21         
22         int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 23         int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 24  button.measure(w, h); 25         
26         int height = button.getMeasuredHeight(); 27         int width = button.getMeasuredWidth(); 28         
29         Log.e("Test", "宽度:" + width); 30         Log.e("Test", "高度:" + height); 31         
32         Log.e("Test", "左上角坐标x:" + button.getLeft()); 33         Log.e("Test", "左上角坐标x:" + button.getTop()); 34 
35         Log.e("Test", "左上角坐标x:" + button.getRight()); 36         Log.e("Test", "左上角坐标x:" + button.getBottom()); 37 
38 
39         
40 
41  } 42 
43 }

运行程序如下:

 

 

(3)我们需要注册一个ViewTreeObserver的监听回调,这个监听回调OnGlobalLayoutListener,就是全局的布局改变监听器,所以是最推荐使用的

ViewTreeObserver:这是一个注册监听视图树的观察者(observer),在视图树种全局事件改变时得到通知。这个全局事件不仅还包括整个树的布局,从绘画过程开始,触摸模式的改变等。ViewTreeObserver不能够被应用程序实例化,因为它是由视图提供,参照getViewTreeObserver()以查看更多信息。

 

 1 package com.himi.test;  2 
 3 import android.app.Activity;  4 import android.os.Bundle;  5 import android.util.Log;  6 import android.view.ViewTreeObserver;  7 import android.view.ViewTreeObserver.OnGlobalLayoutListener;  8 import android.widget.Button;  9 
10 public class MainActivity extends Activity { 11 
12     private Button button; 13 
14  @Override 15     protected void onCreate(Bundle savedInstanceState) { 16         super.onCreate(savedInstanceState); 17  setContentView(R.layout.activity_main); 18 
19         button = (Button) findViewById(R.id.button); 20                  
21 
22         final ViewTreeObserver vto = button.getViewTreeObserver(); 23         vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 24  @Override 25             public void onGlobalLayout() { 26                 button.getViewTreeObserver().removeGlobalOnLayoutListener(this); 27                 int height = button.getMeasuredHeight(); 28                 int width = button.getMeasuredWidth(); 29                 
30 
31                 Log.e("Test", "高度:" + height); 32                 Log.e("Test", "宽度:" + width); 33                 
34                 
35                           
36                          
37                 Log.e("Test", "左上角坐标x:" + button.getLeft()); 38                 Log.e("Test", "左上角坐标y:" + button.getTop()); 39                          
40                 Log.e("Test", "右下角坐标x:" + button.getRight()); 41                 Log.e("Test", "右下角坐标y:" + button.getBottom()); 42 
43  } 44  }); 45  } 46 
47 }

部署程序到手机上,如下:

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM