转自:Android View中getViewTreeObserver().addOnGlobalLayoutListener()

我们知道在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来获得一个视图的真实高度。

  1. int mHeaderViewHeight;
  2. mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener(
  3. new OnGlobalLayoutListener() {
  4. @Override
  5. public void onGlobalLayout() {
  6. mHeaderViewHeight = mHeaderView.getHeight();
  7. getViewTreeObserver()
  8. .removeGlobalOnLayoutListener(this);
  9. }
  10. });
但是需要注意的是OnGlobalLayoutListener可能会被多次触发,因此在得到了高度之后,要将OnGlobalLayoutListener注销掉。




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

类似:

  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高度

Android View中getViewTreeObserver().addOnGlobalLayoutListener() (转)的更多相关文章

  1. Android view中的requestLayout和invalidate方法

    Android view中的requestLayout和invalidate方法 requestLayout:当view确定自身已经不再适合现有的区域时,该view本身调用这个方法要求parent v ...

  2. Android View中的控件和监听方法...

    PS:居然三天没写博客了...今天补上...东西虽多,但是都是一些基础...代码多了一些,有人可能会这样问,粘这么多代码有毛用..其实对于一个Android的初学者来说,一个完整的代码是最容易帮助理解 ...

  3. Android View中滚动相关

    方法   scrollTo: (内容的左上角)达到某个地点 scrollBy: 根据当前位置,再移动多少 属性:   mScrollX, 以下是文档解释   The offset, in pixels ...

  4. android view 中各函数的执行顺数

    这个就好像是 activity 的生命周期一样,如果我们要使用自定义的 view,那么就很有必要了解一下 view 的那些能够被重写的函数的执行顺序.废话不多讲,以常用的5个函数为例子,见下文: pa ...

  5. 字体在Android View中的输出 drawText

    Canvas 作为绘制文本时,使用FontMetrics对象,计算位置的坐标.   public static class FontMetrics {               public flo ...

  6. Android XML中引用自定义内部类view的四个why

    今天碰到了在XML中应用以内部类形式定义的自定义view,结果遇到了一些坑.虽然通过看了一些前辈写的文章解决了这个问题,但是我看到的几篇都没有完整说清楚why,于是决定做这个总结. 使用自定义内部类v ...

  7. Android什么时候进行View中Background的加载

    对大多数Android的开发者来说,最经常的操作莫过于对界面进行布局,View中背景图片的加载是最经常做的.但是我们很少关注这个过程,这篇文章主要解析view中背景图片加载的流程.了解view中背景图 ...

  8. Android UI性能优化实战, 识别View中的性能问题

    出自:[张鸿洋的博客]来源:http://blog.csdn.net/lmj623565791/article/details/45556391 1.概述 2015年初google发布了Android ...

  9. android开发中scrollview添加自定义view的滑动显示问题

    最近做了一个实战用到自定义view,由于view比屏幕大所以想放到scrollview中,如下程序.发现不显示.于是对scrollview进行了研究. <LinearLayout xmlns:a ...

随机推荐

  1. System对象

    System:类中的方法和属性都是静态的 out:标准输出,默认是控制台 in:标准输入.默认是键盘 System:描述系统的一些信息. 获取系统属性信息:Properties getProperti ...

  2. c# Http Post访问接口方式

    一.json格式数据提交返回 提交和返回数据都为json格式 参数提交方式:application/json;charset=UTF-8 统一采用UTF-8字符编码 public string Pos ...

  3. WinForm-SQL查询避免UI卡死

    使用委托,呵呵. Func<List<VM>> act = () => { SqlDataReader reader = DBHelper.ExecuteReader(s ...

  4. PHP登陆提示信息框代码

    出错的提示框 echo "<Script Language='Javascript'>";   echo "alert('提示:用户名密码错误,请重新输入!' ...

  5. json格式在线解析

    地址:https://www.bejson.com/ { "PN": "123456", "DomainName": ".gxyc ...

  6. .Net强大的列表控件XPTable [转]

    .Net强大的列表控件XPTable http://blog.csdn.net/bodybo/article/details/7359531 XPTable的大名,想必C#开发的人都有所耳闻,使用下来 ...

  7. EasyUI Tree 动态传递参数

    1.问题背景 一般出现在加载的时候,传递参数给后台,进行数据筛选,然后在加载tree渲染数据.所谓动态参数,可以是你的上一级节点node,或者是根节点node. 2.涉及方法 onBeforeLoad ...

  8. 2017.5.1 java动态代理总结

    参考来自:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html 1.代理模式 代理类和委托类有相同接口. 代理类负责为委托类:预处理消 ...

  9. 如何使用CodeSmith批量生成代码

    在上一篇我们已经用PowerDesigner创建好了需要的测试数据库,下面就可以开始用它完成批量代码生成的工作啦. 下面我会一步步的解释如何用CodeSmith实现预期的结果的,事先声明一下,在此只做 ...

  10. VB程序无法运行,Component ‘MCI32.OCX’错误怎么办

    1 提示Component 'MCI32.OCX'错误   2 搜索你电脑的MCI32.OCX这个文件   3 把它复制到任意位置,然后再同一个目录下新建一个文本文档,输入regsvr32 MCI32 ...