前言

  • 在activity中,经常需要获取view的width和height,但是在onCreate()获取view的width和height会得到0。view.getWidth()和view.getHeight()为0的根本原因是:控件还没有完成绘制。这种情况当我们使用动态布局(使用wrap_content或match_parent)就会出现。
  • 一般来讲在Activity.onCreate(…)、onResume()方法中都没有办法获取到View的实际宽高。So,我们必须用一种变通的方法,等到View绘制完成后去获取width和Height。
  • 下面有一些可行的解决方案:

1. 监听Draw/Layout事件:ViewTreeObserver

ViewTreeObserver监听很多不同的界面绘制事件。一般来说OnGlobalLayoutListener就是可以让我们获得到view的width和height的地方.下面onGlobalLayout内的代码会在View完成Layout过程后调用。

view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {        @Override        public void onGlobalLayout() {            mScrollView.post(new Runnable() {                public void run() {                    view.getHeight(); //height可用了                }            });        }});

但是要注意这个方法在每次有些view的Layout发生变化的时候被调用(比如某个View被设置为Invisible),所以在得到你想要的宽高后,记得移除onGlobleLayoutListener:

在 SDK Lvl < 16时使用public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)在 SDK Lvl >= 16时使用public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)
2. 将一个runnable添加到Layout队列中:View.post()

这个解决方案是比较好的。简单地说,只要用View.post()一个runnable就可以了。runnable对象中的方法会在View的measure、layout等事件后触发,UI事件队列会按顺序处理事件。在setContentView()被调用后,事件队列中会包含一个要求重新layout的message,所以任何post到队列中的东西都会在Layout发生变化后执行。

view.post(new Runnable() {        @Override        public void run() {            view.getHeight(); //height可用        }    });
3. 重写View的onLayout方法

这个方法谨慎使用,一般用在:所要执行的代码应该作为内部逻辑,从而实现高内聚的view模块,否者这个解决方案就显得很耦合、拖拉。

view = new View(this) {    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        super.onLayout(changed, l, t, r, b);        view.getHeight(); //height可用    }};

需要注意的是onLayout方法会被调用很多次,所以要考虑好在这个方法中要做什么,或者在第一次执行后禁用掉代码。

4. 重写Activity的onWindowFocusChanged方法

如果要获取的view的width和height是固定的,那么可以直接使用:

@Overridepublic void onWindowFocusChanged(boolean hasFocus) {    super.onWindowFocusChanged(hasFocus);    //此处可以正常获取width、height等}

在Activity得到或者失去焦点的时候,就会被调用。Activity初始化完毕准备显示的时候就会回调该方法。所以说,只要想做一些Activity加载完毕就马上触发的事情,都可以在这里执行。

5. 获取固定宽高

如果要获取的view的width和height是固定的,那么可以直接使用:

View.getMeasureWidth()View.getMeasureHeight()

更多相关文章

  1. Android图像处理之Bitmap类
  2. [置顶] android 多线程Thread,Runnable,Handler,AsyncTask等之间
  3. 第25章、OnTouchListener触摸事件(从零开始学Android)
  4. Android(安卓)ADB 找不到设备的解决方法
  5. Android(安卓):Kernel Uevent发送(热插拔)事件到用户空间
  6. 初学Android,数据存储之SharedPreferences(四十一)
  7. android 预装第三方apk的方法(非system priv-app)
  8. Android之View基础总结(View的事件体系一)
  9. Android(安卓)TextView使用HTML处理字体样式、显示图片等

随机推荐

  1. Android(安卓)LinearLayout等配置圆角背
  2. Android传感器
  3. Unity调用Android录音
  4. Android(安卓)SMS(一) —— 读取短信
  5. Android(安卓)studio R8 编译报错
  6. Android(安卓)Wear
  7. android获取短信所有内容
  8. json解析android客户端源码
  9. Android(安卓)两种HTTP Client的比较
  10. widget(1、TextView)