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的高度、宽度、坐标值的更多相关文章

  1. Android进阶笔记18:选用合适的IPC方式

    1. 相信大家都知道Android进程间通信方式很多,比如AIDL.Messenger等等,接下来我就总结一下这些IPC方式优缺点. 2. IPC方式的优缺点和适用场景 3. 附加:使用Intent实 ...

  2. Android进阶笔记:Messenger源码详解

    Messenger可以理解为一个是用于发送消息的一个类用法也很多,这里主要分析一下再跨进程的情况下Messenger的实现流程与源码分析.相信结合前面两篇关于aidl解析文章能够更好的对aidl有一个 ...

  3. Android进阶笔记:AIDL内部实现详解 (二)

    接着上一篇分析的aidl的流程解析.知道了aidl主要就是利用Ibinder来实现跨进程通信的.既然是通过对Binder各种方法的封装,那也可以不使用aidl自己通过Binder来实现跨进程通讯.那么 ...

  4. 我的Android进阶之旅------>如何获取系统中定义了那些权限

    在Window控制台中输入如下命令可以看到Android系统中列出的所有权限(如果自定义权限注册成功,在这里也会找到这些自定义的权限) adb shell pm list permissions C: ...

  5. 我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)

    正如在<我的Android进阶之旅------>Android疯狂连连看游戏的实现之状态数据模型(三)>一文中看到的,在AbstractBoard的代码中,当程序需要创建N个Piec ...

  6. 我的Android进阶之旅------>Android疯狂连连看游戏的实现之开发游戏界面(二)

    连连看的游戏界面十分简单,大致可以分为两个区域: 游戏主界面区 控制按钮和数据显示区 1.开发界面布局 本程序使用一个RelativeLayout作为整体的界面布局元素,界面布局上面是一个自定义组件, ...

  7. 我的Android进阶之旅------>Android颜色值(#AARRGGBB)透明度百分比和十六进制对应关系以及计算方法

    我的Android进阶之旅-->Android颜色值(RGB)所支持的四种常见形式 透明度百分比和十六进制对应关系表格 透明度 十六进制 100% FF 99% FC 98% FA 97% F7 ...

  8. 我的Android进阶之旅------>Android利用温度传感器实现带动画效果的电子温度计

    要想实现带动画效果的电子温度计,需要以下几个知识点: 1.温度传感器相关知识. 2.ScaleAnimation动画相关知识,来进行水印刻度的缩放效果. 3.android:layout_weight ...

  9. 我的Android进阶之旅------>Android实现用Android手机控制PC端的关机和重启的功能(三)Android客户端功能实现

    我的Android进阶之旅------>Android实现用Android手机控制PC端的关机和重启的功能(一)PC服务器端(地址:http://blog.csdn.net/ouyang_pen ...

随机推荐

  1. LinqProvider系列(三)如何实现自己的Linq Provider?

    这篇文章将在前人的肩上,继续完成实现Linq Provider的任务. 首先,我们列出linq语法的解析过程: linq本质上就是把我们惯用的语法糖,变成了一颗表达式树,然后由不同的linq Prov ...

  2. Java注解(二)

    前面了解了注解的基本内容,这次来看一下自定义注解. 自定义注解其实很简单,直接上代码: import java.lang.annotation.Documented; import java.lang ...

  3. CentOS 7 隐藏任务栏和顶栏

    我使用的是Gnome,对于使用惯了windows的我来说,这个界面确实有点丑,但是,也将就着用了,最近发现有一款软件(Cairo-Dock)可以美化桌面,于是就安装了,但是安装之后发现了一个问题:原来 ...

  4. 【学习笔记】--- 老男孩学Python,day15 python内置函数大全,递归,二分法

    1. lamda匿匿名函数2. sorted()3. filter()4. map()5. 递归函数 一. lamda 匿名函数 为了了解决一些简单的需求⽽设计的⼀句话函数 语法: 函数名 = lam ...

  5. 微信小程序--分享界面自定义图片

    一般小程序页面都会大于等于1页,每个页面右上角都会有分享功能,建议把以下方法封装到app.js文件,在页面直接调用该方法,避免重复代码,提高性能.(代码用到ES6语法,若不支持,请自行还原js) // ...

  6. PHP中文件操作(2)-- 写文件

    1.fread — 读取文件(可安全用于二进制文件) 语法:string fread ( int $handle , int $length ) $filename = "aa.txt&qu ...

  7. 关于nginx下drupal7无法$_GET获取参数的问题

    参考:nginx 官方drupal 配置 - Drupal | NGINX 之前配置好了LNMP下的drupal7(7.59版本),简洁路径也配好了.但是在使用过程出现问题. 配置的nginx.con ...

  8. JavaScript、HTML、CSS学习—思维导图

  9. 网络I/O模型--03非阻塞模式(ServerSocket与Socket的超时处理)--解除accept()、 read()方法阻塞

    对于阻塞方式的一种改进是在应用程序层面上将 “一直等待 ”的状态主动打开: 这种模式下,应用程序的线程不再一直等待操作系统的 I/O状态,而是在等待一段时间后就解除阻塞.如果没有得到想要的结果,则再次 ...

  10. java基础(二) 自增自减与贪心规则

    引言   JDK中提供了自增运算符++,自减运算符--.这两个操作符各有两种使用方式:前缀式(++ a,--a),后缀式(a++,a--).可能说到这里,说不得有读者就会吐槽说,前后缀式都挺简单的,前 ...