转自: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高度

最新文章

  1. C#执行Dos命令公用方法
  2. C#的HTTP协议中POST与GET的区别
  3. Printf()输出格式控制(转)
  4. IOS网络编程。。
  5. LabView中,下拉列表和枚举有什么区别?
  6. Javascript操纵Cookie--转
  7. 初次了解CSS3
  8. StrPos,StrScan,
  9. Git中的merge命令实现中出现问题及其解决
  10. 单例模式(Singleton)看了就懂
  11. 神奇的 routing mesh - 每天5分钟玩转 Docker 容器技术(100)
  12. Python 抽象篇:面向对象之高阶用法
  13. [LeetCode] Equal Tree Partition 划分等价树
  14. GET和POST两种基本请求方法(转自博主--在途中#)
  15. [Docker] sh: docker-compose: not found
  16. [luogu P3953] [noip2017 d1t3] 逛公园
  17. PostgreSQL 问题总结
  18. 百度统计api获取数据
  19. Windows Server 2012 R2域控制器部署
  20. Lftp 简单使用步骤

热门文章

  1. linux安装mysql数据库(5.7之前的版本)
  2. hdu 1015 Safecracker 水题一枚
  3. iOS禁止多点操作(按钮和Table项)
  4. mybatis学习笔记(六)使用generator生成mybatis基础配置代码和目录结构
  5. NSPredicate 条件查询或过虑
  6. Introduction to the TestFlight SDK
  7. ubuntu16.04 ssh服无法远程连接解决办法
  8. appium window64安装教程
  9. wsdl2java在mac中点配置
  10. 倍福TwinCAT(贝福Beckhoff)基础教程 松下伺服驱动器报错 81.0怎么办