Android解决在onCreate()中获取View的width、Height为0的方法

前言

  • 在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是固定的,那么可以直接使用:

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

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

5. 获取固定宽高

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

View.getMeasureWidth()
View.getMeasureHeight()

你可能感兴趣的:(Android解决在onCreate()中获取View的width、Height为0的方法)