如何获取view的大小

 

很多初学者都会犯一个错误 ,就是在onCreate或者onStart里面去获取view的大小,然而这样获取到的宽高通常都是0,为什么呢?因为view的测量过程和activity的生命周期不是同步的,因此无法保证执行了onCreate、onStart、onResume的时候view已经测量完毕。如果还没测量完,那么获取到的宽高就会是0。

那么我们应该在哪里获取view的大小呢?以下有几种办法:

1、在onWindowFocusChanged里面获取。

这个方法是当Activity的窗口失去焦点或者获取焦点的时候就会调用,比如进行onResume或者onPause的时候,它就会被调用(因此它有可能被多次调用)。我们可以用下面的模板来获取view的宽高。

public void onWindowFocusChanged(boolean hasFocus)
{
    super.onWindowFocusChanged(hasFocus);
    if(hasFocus)
    {
      int width=view.getMeasuredWidth();
      int height=view.getMeasuredHeight();
    }
}

 

2、使用view.post(runnable).

通过这个方法可以把一个runnable任务投递到消息队列的尾部。在该方法里面,会先获取view所在线程的handler(view所在的线程当然就是UI线程),然后将任务投递到handler所对应的消息队列的尾部,等待looper去获取,当looper获取到的时候,view已经初始化完毕,所以就能正确的获取它的宽高了。代码模板如下:

protected void onStart()
    {
        super.onStart();
        view.post(new Runnable(){
            @Override
            public void run() {
                int width=view.getMeasuredWidth();
                int height=view.getMeasuredHeight();
            }
        });
    }


3、使用ViewTreeObserver

ViewTreeObserve有许多回调接口,比如OnGlobalLayoutListener这个接口,当view树的状态发生改变的时候,或者view树内部view的可见性发生改变的时候,该接口里面的onGlobalLayout方法将被回调,可以在这个时候获取view的宽高。因此该方法可能会被多次调用,我们应当在获取到view的宽高之后把该接口监听移除。代码模板如下:

@Override
    protected void onStart() {
        super.onStart();
        ViewTreeObserver observer=view.getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                int width=view.getMeasuredWidth();
                int height=view.getMeasuredHeight();
            }
        });
    }

 

以上便是获取view大小的三种常用的方法。

 

posted @ 2017-06-18 21:11 妖久 阅读(...) 评论(...) 编辑 收藏