Android 在onCreate()方法中获取控件宽高值为0解决方案

大家很多时候需要在Activity或者Fragment的onCreate()方法中获取声明的空间的高度或者宽度,进行位置移动或者其他操作,但是当调用 view.getHeight() 或者 view.getWidth() 获取的竟然为0。。。

其实很容易理解,在onCreate()的时候,实际上控件只是声明了,并没有绘制完成,没有attach到window上,所以导致获取的高度和宽度为0,那么该怎么解决呢?

三种方式

1、使用下面的post方式

view.post(new Runnable() {
     @Override
     public void run() {
         int height = view.getHeight() ;
         int width = view.getWidth();
      }
});

原理:

  • View.post(Runnable) 内部会自动分两种情况处理,当 View 还没 attachedToWindow 时,会先将这些 Runnable 操作缓存下来;否则就直接通过 mAttachInfo.mHandler 将这些 Runnable 操作 post 到主线程的 MessageQueue 中等待执行。

  • 如果 View.post(Runnable) 的 Runnable 操作被缓存下来了,那么这些操作将会在 dispatchAttachedToWindow() 被回调时,通过 mAttachInfo.mHandler.post() 发送到主线程的 MessageQueue 中等待执行。

想了解更多请去查看源码。相信你可以更深层次的理解。

View.post() 中的操作执行时,View 的宽高已经计算完毕,所以可以在 Activity 的 onCreate() 里调用 View.post() 来解决获取 View 宽高为0的问题

2、使用ViewTreeObserver的方式

ViewTreeObserver vto = view.getRabbit().getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
    public boolean onPreDraw() {
        if(vto.isAlive()){
            vto.removeOnDrawListener(this);
        }
        int height = view.getMeasuredHeight());
        return true;
    }
});

ViewTreeObserver 注册一个观察者来监听视图树,当视图树的布局、视图树的焦点、视图树将要绘制、视图树滚动等发生改变时,ViewTreeObserver都会收到通知。所以 这个方法会调用很多次,如果要使用这种方法的话,要做好规避调用多次,记得移除监听;ViewTreeObserver不能被实例化,可以调用View.getViewTreeObserver()来获得。

3、还有一种不太推荐

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    int height = view.getHeight()
    int width = view.getHeight();
}

这个函数的含义是:view已经初始化完毕了,宽/高已经准备好了,这个时候去获取宽高是可以成功获取的。需要注意的是 onWindowFocusChanged函数会被调用多次,当Activity的窗口得到焦点和失去焦点时均会被调用一次,如果频繁地进行onResume和onPause,那么onWindowFocusChanged也会被频繁地调用,不太适合处理一些复杂的业务逻辑

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章