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 }
部署程序到手机上,如下: