我们知道在oncreate中View.getWidth和View.getHeight无法获得一个view的高度和宽度,这是因为View组件布局要在onResume回调后完成。所以现在需要使用getViewTreeObserver().addOnGlobalLayoutListener()来获得宽度或者高度。这是获得一个view的宽度和高度的方法之一。

OnGlobalLayoutListener 是ViewTreeObserver的内部类,当一个视图树的布局发生改变时,可以被ViewTreeObserver监听到,这是一个注册监听视图树的观察者(observer),在视图树的全局事件改变时得到通知。ViewTreeObserver不能直接实例化,而是通过getViewTreeObserver()获得。

除了OnGlobalLayoutListener ,ViewTreeObserver还有如下内部类:

interface ViewTreeObserver.OnGlobalFocusChangeListener 当在一个视图树中的焦点状态发生改变时,所要调用的回调函数的接口类 interface ViewTreeObserver.OnGlobalLayoutListener 当在一个视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变时,所要调用的回调函数的接口类 interface ViewTreeObserver.OnPreDrawListener 当一个视图树将要绘制时,所要调用的回调函数的接口类 interface ViewTreeObserver.OnScrollChangedListener 当一个视图树中的一些组件发生滚动时,所要调用的回调函数的接口类 interface ViewTreeObserver.OnTouchModeChangeListener 当一个视图树的触摸模式发生改变时,所要调用的回调函数的接口类

其中,我们可以利用OnGlobalLayoutListener来获得一个视图的真实高度

[java] view plain copy print ?
  1. int mHeaderViewHeight;  
  2. mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener(  
  3.         new OnGlobalLayoutListener() {  
  4.             @Override  
  5.             public void onGlobalLayout() {  
  6.                                                                                                                                                                                                                                         
  7.                 mHeaderViewHeight = mHeaderView.getHeight();  
  8.                 getViewTreeObserver()  
  9.                         .removeGlobalOnLayoutListener(this);  
  10.             }  
  11.         });  

但是需要注意的是 OnGlobalLayoutListener 可能会被多次触发,因此在得到了高度之后,要将 OnGlobalLayoutListener 注销掉。
   

有时候需要在onCreate方法中知道某个View组件的宽度和高度等信息,而直接调用View组件的getWidth()、getHeight()、getMeasuredWidth()、getMeasuredHeight()、getTop()、getLeft()等方法是无法获取到真实值的,只会得到0。这是因为View组件布局要在onResume回调后完成。下面提供实现方法,onGlobalLayout回调会在view布局完成时自动调用:

类似:

[java] view plain copy print ?
  1. // This listener is used to get the final width of the GridView and then calculate the  
  2. // number of columns and the width of each column. The width of each column is variable  
  3. // as the GridView has stretchMode=columnWidth. The column width is used to set the height  
  4. // of each view so we get nice square thumbnails.  
  5. mGridView.getViewTreeObserver().addOnGlobalLayoutListener( //view 布局完成时调用,每次view改变时都会调用  
  6.         new ViewTreeObserver.OnGlobalLayoutListener() {  
  7.             @Override  
  8.             public void onGlobalLayout() {  
  9.                 if (mAdapter.getNumColumns() == 0) {  
  10.                         final int numColumns = (int) Math.floor(  
  11.                                  mGridView.getWidth() / (mImageThumbSize + mImageThumbSpacing));  
  12.                     if (numColumns > 0) {  
  13.                         final int columnWidth =  
  14.                             (mGridView.getWidth() / numColumns) - mImageThumbSpacing;  
  15.                         mAdapter.setNumColumns(numColumns);   //设置 列数  
  16.                             mAdapter.setItemHeight(columnWidth);  //设置 高度  
  17.                     }  
  18.                 }  
  19.             }  
  20.         });  

在gridview布局完成后,根据girdview的宽和高设置adapter列数和每个item高度

更多相关文章

  1. Android(安卓)AIDL浅析及异步调用
  2. Android(安卓)8.0 dexopt记录
  3. Android中getView与inflate方法的详解
  4. 天天记录 - Android(安卓)使用view.ScrollBy实现View随手指移动
  5. (20120731)android面试总结(003)
  6. Android(安卓)- View的绘制流程二(layout)
  7. Android(安卓)ISurface PostBuffer 处理流程
  8. Android下在onCreate方法中获取TextView的高度
  9. Android(安卓)onPause和onSaveInstanceState的区别

随机推荐

  1. Android(安卓)App发布流程----签名
  2. android-UI组件实例大全(十六)---菜单Men
  3. Android中内嵌字体实现个性化
  4. android三个特殊的资源目录 /res/xml /re
  5. Android(安卓)运行时权限浅谈
  6. Android学习笔记——从源码看Handler的处
  7. Android免费获取短信验证码
  8. 聆听Google立足于iOS的设计之声
  9. Bluetooth 4.0之Android(安卓)讲解
  10. Android之DDMS初探