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 }

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

 

转载于:https://www.cnblogs.com/hebao0514/p/5750640.html

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐