在onCreate中获取View宽高的三种方法

前言

很多时候,我们在动态创建View时,需要获取View的宽高。这时,如果你在onCreate、onStart、onResume中直接调用View的getWidth/getHeight方法,均无法得到View宽/高的正确信息。这是因为view的measure过程与Activity的生命周期是不同步的。这就无法保证在onCreate、onStart、onResume中view的measure已经完成。若view的measure此时正在进行,那么获得的宽/高就是0。这里我将给出三种方案来解决这个问题。

万能的view.post()方法。

曾经有个同事对我说过这样一句话,他说,在他遇到各种莫名奇妙的UI问题的时候,他最先尝试的就是view.post方法,而且有效率极高。当然,view.post方法在解决这个问题上也是有效的。将一个runnable对象放到主线程的末尾去执行,这时view已经measure、layout、draw完成。因此,此方法是有效的。代码如下:

        view.post(new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                int width = view.getWidth();
                int hight = view.getHeight();
            }
        });

Activity的onWindowFocusChanged方法

onWindowFocusChanged,通过名字我们就可以推测出该方法的含义:当Activity的窗口得到焦点或者失去焦点的时候会调用该方法一次。当Activity获取焦点时,说明View已经初始化完毕。此时,调用view的getWidth()/getHeight()方法是没有问题的。需要注意的是,若Activity频繁的失去、得到焦点那么该方法会被频繁的调用。

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        // TODO Auto-generated method stub
        super.onWindowFocusChanged(hasFocus);
        if(hasFocus){
            int width = view.getWidth();
            int hight = view.getHeight();
        }
    }

为ViewTreeObserver注册OnGlobalLayoutListener接口

ViewTreeObserver是一个观察者,主要是用来观察视图树的各种变化。OnGlobalLayoutListener的作用是当View树的状态发生改变或者View树中某view的可见性发生改变时,OnGlobalLayoutListener的onGlobalLayout方法将会被回调。因此,此时获取view的宽/高也是可以的。与onWindowFocusChanged类似,当view树的状态多次发生改变时,onGlobalLayout会被调用多次。

        ViewTreeObserver observer = title_name.getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            
            @Override
            public void onGlobalLayout() {
                // TODO Auto-generated method stub
               int width = view.getWidth();
               int hight = view.getHeight();
            }
        });
参考书籍

Anroid开发艺术探索

你可能感兴趣的:(在onCreate中获取View宽高的三种方法)