Android进阶笔记18:Android 获取Button的高度、宽度、坐标值
1. 问题
如何获取一个控件的长和高,相信很多朋友第一眼看见这个问题都会觉得很简单,直接在onCreate里面调用getWidth、getMeasuredWidth不就可以获得了吗,但是,事实上是并没有简单的,不信的话,你可以去试一下,在onCreate里面,你是无法获得长宽值的,始终为0。
package com.himi.test; import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.Button; public class MainActivity extends Activity { private Button button; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button);
Log.e("Test", "getWidth宽度:" + button.getWidth());
Log.e("Test", "getHeight高度:" + button.getMeasuredWidth());
} }
程序运行结果如下:

2. 原因
这是为什么呢,其实熟悉view绘制流程的朋友应该一眼就看出来了,在onCreate中,我们的控件其实还并没有画好,换句话说,等onCreate方法执行完了,我们定义的控件才会被度量(measure),所以我们在onCreate方法里面通过view.getHeight()获取控件的高度或者宽度肯定是0。
3. 获取Button的高度、宽度、坐标值:
(1)利用延时(保证onCreate先完成):
package com.himi.test; import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.Button; public class MainActivity extends Activity { private Button button; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button);
Log.e("Test", "getWidth宽度:" + button.getWidth());
Log.e("Test", "getHeight高度:" + button.getMeasuredWidth()); new Thread() { @Override
public void run() {
synchronized (this) {
try {
wait(1000);// 1秒
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} Log.e("Test", "高度:" + button.getHeight());
Log.e("Test", "宽度:" + button.getWidth()); Log.e("Test", "左上角坐标x:" + button.getLeft());
Log.e("Test", "左上角坐标y:" + button.getTop()); Log.e("Test", "右下角坐标x:" + button.getRight());
Log.e("Test", "右下角坐标y:" + button.getBottom()); }
}.start(); } }
运行程序如下:

(2)自己使用API测量:
package com.himi.test; import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button; public class MainActivity extends Activity { private Button button; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
button.measure(w, h); int height = button.getMeasuredHeight();
int width = button.getMeasuredWidth(); Log.e("Test", "宽度:" + width);
Log.e("Test", "高度:" + height); Log.e("Test", "左上角坐标x:" + button.getLeft());
Log.e("Test", "左上角坐标x:" + button.getTop()); Log.e("Test", "左上角坐标x:" + button.getRight());
Log.e("Test", "左上角坐标x:" + button.getBottom()); } }
运行程序如下:
(3)我们需要注册一个ViewTreeObserver的监听回调,这个监听回调OnGlobalLayoutListener,就是全局的布局改变监听器,所以是最推荐使用的:
ViewTreeObserver:这是一个注册监听视图树的观察者(observer),在视图树种全局事件改变时得到通知。这个全局事件不仅还包括整个树的布局,从绘画过程开始,触摸模式的改变等。ViewTreeObserver不能够被应用程序实例化,因为它是由视图提供,参照getViewTreeObserver()以查看更多信息。
package com.himi.test; import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.Button; public class MainActivity extends Activity { private Button button; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); final ViewTreeObserver vto = button.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
button.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int height = button.getMeasuredHeight();
int width = button.getMeasuredWidth(); Log.e("Test", "高度:" + height);
Log.e("Test", "宽度:" + width); Log.e("Test", "左上角坐标x:" + button.getLeft());
Log.e("Test", "左上角坐标y:" + button.getTop()); Log.e("Test", "右下角坐标x:" + button.getRight());
Log.e("Test", "右下角坐标y:" + button.getBottom()); }
});
} }
部署程序到手机上,如下:

Android进阶笔记18:Android 获取Button的高度、宽度、坐标值的更多相关文章
- Android进阶笔记18:选用合适的IPC方式
1. 相信大家都知道Android进程间通信方式很多,比如AIDL.Messenger等等,接下来我就总结一下这些IPC方式优缺点. 2. IPC方式的优缺点和适用场景 3. 附加:使用Intent实 ...
- Android进阶笔记:Messenger源码详解
Messenger可以理解为一个是用于发送消息的一个类用法也很多,这里主要分析一下再跨进程的情况下Messenger的实现流程与源码分析.相信结合前面两篇关于aidl解析文章能够更好的对aidl有一个 ...
- Android进阶笔记:AIDL内部实现详解 (二)
接着上一篇分析的aidl的流程解析.知道了aidl主要就是利用Ibinder来实现跨进程通信的.既然是通过对Binder各种方法的封装,那也可以不使用aidl自己通过Binder来实现跨进程通讯.那么 ...
- 我的Android进阶之旅------>如何获取系统中定义了那些权限
在Window控制台中输入如下命令可以看到Android系统中列出的所有权限(如果自定义权限注册成功,在这里也会找到这些自定义的权限) adb shell pm list permissions C: ...
- 我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)
正如在<我的Android进阶之旅------>Android疯狂连连看游戏的实现之状态数据模型(三)>一文中看到的,在AbstractBoard的代码中,当程序需要创建N个Piec ...
- 我的Android进阶之旅------>Android疯狂连连看游戏的实现之开发游戏界面(二)
连连看的游戏界面十分简单,大致可以分为两个区域: 游戏主界面区 控制按钮和数据显示区 1.开发界面布局 本程序使用一个RelativeLayout作为整体的界面布局元素,界面布局上面是一个自定义组件, ...
- 我的Android进阶之旅------>Android颜色值(#AARRGGBB)透明度百分比和十六进制对应关系以及计算方法
我的Android进阶之旅-->Android颜色值(RGB)所支持的四种常见形式 透明度百分比和十六进制对应关系表格 透明度 十六进制 100% FF 99% FC 98% FA 97% F7 ...
- 我的Android进阶之旅------>Android利用温度传感器实现带动画效果的电子温度计
要想实现带动画效果的电子温度计,需要以下几个知识点: 1.温度传感器相关知识. 2.ScaleAnimation动画相关知识,来进行水印刻度的缩放效果. 3.android:layout_weight ...
- 我的Android进阶之旅------>Android实现用Android手机控制PC端的关机和重启的功能(三)Android客户端功能实现
我的Android进阶之旅------>Android实现用Android手机控制PC端的关机和重启的功能(一)PC服务器端(地址:http://blog.csdn.net/ouyang_pen ...
随机推荐
- BG.Sqoop
1. 下载 Sqoop,并复制到虚拟机 http://sqoop.apache.org/ 2. 安装Sqoop tar zxf sqoop-1.4.6.bin__hadoop-2.0.4-alpha. ...
- MySql__centos6.5源码安装
安装MySql步骤如下: 依赖包检查安装 配置防火墙 配置hosts文件 配置sysctl.cnf 检查是否安装mysql 如果有卸载掉(指的是没有用的mysql) 创建用户属组 创建相应目录并修改权 ...
- Struts2和MVC的简单整合
1.首先还是创建一个简单Maven的项目,导入jar包, <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:x ...
- Java使用Redisson分布式锁实现原理
本篇文章摘自:https://www.jb51.net/article/149353.htm 由于时间有限,暂未验证 仅先做记录.有大家注意下哈(会尽快抽时间进行验证) 1. 基本用法 添加依赖 &l ...
- WireShark 过滤 SSDP
在局域网中使用wireshark抓包过滤http的时候经常会出现一些干扰协议,例如SSDP,使用过滤条件"http"有可能出现N多ssdp包,如下图所示: SSDP:Simple ...
- redux、immutablejs和mobx性能对比(一)
一.前言 关于react的性能优化,有很多方面可以去做,而其中避免重复渲染又是比较重要的一点,那么为什么react会重复渲染,我们又该如何避免重复渲染呢,关于这方面官方其实早有说明:避免重复渲染,这里 ...
- iTem2 保持连接,解决ssh的"Write failed: Broken pipe"问题
方法一: profiles -> sessions -> When idel, send ASCII code 问题场景 服务器环境:阿里云 Linux CentOS 主机 客户端:Mac ...
- elixir mac环境
1.升级brew brew update 2.安装 erlang brew install erlang 3.安装Elixir: brew install elixir 终端 iex iex> ...
- Android属性动画简单剖析
运行效果图: 先看布局文件吧,activity_main.xml: <?xml version="1.0" encoding="utf-8"?> & ...
- linux centos7最小化安装桥接模式网络设置、xshell、xftf
一.网络连接设置1.桥接模式 使用电脑真实网卡,可以和自己的电脑连接,也可以和外部网络连接2.NAT模式 使用wmware network adapter vmnet8虚拟网卡,可以和自己的电脑连接, ...