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. 解决vuejs应用在nginx非根目录下部署时访问404的问题

    以往部署vuejs应用都是直接在nginx的location为/下直接部署,这次遇到要将vue应用部署在/vuejs-admin的非根下,使用以往部署方案直接访问就会404,这时修改步骤如下: 1.修 ...

  2. [日常] SinaMail项目和技术能力总结

    一.企邮WEBMAIL项目1.完成手机绑定二次验证,绑定手机提升账户的安全性2.登陆验证接口改造,增加一系列登陆限制,增强webmail的系统可靠性3.增加外发限制功能,及时控制用户发信行为,有利于企 ...

  3. 控制器pop时没有被销毁(没有走dealloc方法)错误原因

    ARC环境下,不需要我们进行过多的内存的管理我们需要做的就是在dealloc方法中进行内存管理,但是错误的代码也会造成内存管理方法dealloc不执行,错误的原因无非以下三种,其中第二种和第三种最容易 ...

  4. mongodb常用的查询命令例子

    取 time 字段的最大值: db.getCollection('CallLog').find().sort({"time":-1}).limit(1) 最小值只需要把 –1 改成 ...

  5. Hive可视化工具

    目前市面上的Hive可视化客户端工具,大都是C/S模式的,安装使用都不是太方便,目前有一款基于WEB的可视化工具TreeSoft,通过浏览器就可以访问使用了,并且可以同时管理.维护.监控MySQL,O ...

  6. POJ1321(KB1-A 简单搜索)

    棋盘问题 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 40872 Accepted: 19936 Description 在一 ...

  7. 总结oninput、onchange与onpropertychange事件的使用方法和差别

    onchange事件仅仅在键盘或者鼠标操作改变对象属性,且失去焦点时触发,脚本触发无效:而onkeydown/onkeypress/onkeyup在处理复制.粘贴.拖拽.长按键(按住键盘不放)等细节上 ...

  8. ios 下拉列表

    #import <UIKit/UIKit.h> @class FVPullDownMenu; /** 指示器状态*/ typedef enum { IndicatorStateShow = ...

  9. Android RxJava+Retrofit完美封装

    作者简介 本篇来自 小河马 的投稿,分享了自己是如何进行 RxJava+Retrofit 的封装.本文的技术点自然没话说,另外对于这种模块化的思路,希望能帮助到大家.最后提前祝大家周末愉快以及圣诞快乐 ...

  10. ios虚拟机安装 (三)

    安装mac系统出现欢迎使用的界面-->一直继续(个人设定) 点击左上角-->Dock-->启动放大 Safari 浏览器