当我们动态创建某些View时,需要通过获取他们的width和height来确定别的view的布局,但是在onCreate()获取view的width和height会得到0.

view.getWidth()和view.getHeight()为0的根本原因是控件还没有完成绘制,你必须等待系统将绘制完View时,才能获得。

这种情况当你需要使用动态布局(使用wrap_content或match_parent)就会出现。

一般来讲在Activity.onCreate(...)、onResume()方法中都没有办法获取到View的实际宽高。所以,我们必须用一种变通的方法,等到View绘制完成后去获取width和Height。

下面有一些可行的解决方案。

1、监听Draw/Layout事件:ViewTreeObserver

ViewTreeObserver监听很多不同的界面绘制事件。一般来说OnGlobalLayoutListener就是可以让我们获得到view的width和height的地方.下面onGlobalLayout内的代码会在View完成Layout过程后调用。

view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {@Overridepublic void onGlobalLayout() {view.getHeight(); //height is ready}
});

但是要注意这个方法在每次有些view的Layout发生变化的时候被调用(比如某个View被设置为Invisible),所以在得到你想要的宽高后,记得移除onGlobleLayoutListener:

在 SDK Lvl < 16时使用
public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)在 SDK Lvl >= 16时使用
public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {@Overridepublic void onGlobalLayout() {view.height;//width and height is readyif (SDK>=16) {view.getViewTreeObserver().removeOnGlobalLayoutListener(this);} else {headerView.getViewTreeObserver().removeGlobalOnLayoutListener(this);}}});

2、将一个runnable添加到Layout队列中:View.post()

这个解决方案是我最喜欢的,但是几乎没人知道有这个方法。

简单地说,只要用View.post()一个runnable就可以了。runnable对象中的方法会在View的measure、layout等事件后触发,具体的参考Romain Guy:

The UI event queue will process events in order. After setContentView() is invoked, the event queue will contain a message asking for a relayout, so anything you post to the queue will happen after the layout pass. – Romain Guy Jul 9 '12 at 18:39

final View view=//smth;
...
view.post(new Runnable() {@Overridepublic void run() {view.getHeight(); //height is ready}});

这个方法比ViewTreeObserver好:
1、你的代码只会执行一次,而且你不用在在每次执行后将Observer禁用,省心多了。
2、语法很简单

参考:
http://stackoverflow.com/a/3602144/774398
http://stackoverflow.com/a/3948036/774398

3、重写View的onLayout方法

这个方法只在某些场景中实用,比如当你所要执行的东西应该作为他的内在逻辑被内聚、模块化在view中,否则这个解决方案就显得十分冗长和笨重。

view = new View(this) {@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b);view.getHeight(); //height is ready}
};

需要注意的是onLayout方法会调用很多次,所以要考虑好在这个方法中要做什么,或者在第一次执行后禁用掉你的代码。

附加:获取固定宽高

如果你要获取的view的width和height是固定的,那么你可以直接使用:

1 View.getMeasureWidth()
2 View.getMeasureHeight()

但是要注意,这两个方法所获取的width和height可能跟实际draw后的不一样。官方文档解释了不同的原因:

View的大小由width和height决定。一个View实际上同时有两种width和height值。

第一种是measure width和measure height。他们定义了view想要在父View中占用多少width和height(详情见Layout)。measured height和width可以通过getMeasuredWidth() 和 getMeasuredHeight()获得。

第二种是width和height,有时候也叫做drawing width和drawing height。这些值定义了view在屏幕上绘制和Layout完成后的实际大小。这些值有可能跟measure width和height不同。width和height可以通过getWidth()和getHeight获得。

参考链接

https://stackoverflow.com/questions/3591784/getwidth-and-getheight-of-view-returns-0/24035591#24035591

From:http://www.cnblogs.com/kissazi2/p/4133927.html

如何解决在onCreate()中获取View的width和Height为0?相关推荐

  1. android中oncreate方法,Android解决在onCreate()中获取View的width、Height为0的方法

    前言 在activity中,经常需要获取view的width和height,但是在onCreate()获取view的width和height会得到0.view.getWidth()和view.getH ...

  2. 解决在onCreate()过程中获取View的width和Height为0的4种方法

    此博客为转载,原文请看这位老铁的文章: https://www.cnblogs.com/kissazi2/p/4133927.html 很经常当我们动态创建某些View时,需要通过获取他们的width ...

  3. spring mvc DispatcherServlet详解之三---request通过ModelAndView中获取View实例的过程

    整个spring mvc的架构如下图所示: 上篇文件讲解了DispatcherServlet第二步:通过request从Controller获取ModelAndView.现在来讲解第三步:reques ...

  4. java数据存在ie中_[Java教程]解决在IE中获取数据的缓存问题,运行环境为node.js

    [Java教程]解决在IE中获取数据的缓存问题,运行环境为node.js 0 2015-11-30 20:00:06 IE下默认会开启缓存策略,不管是页面还是通过ajax请求的数据都会议一个url,u ...

  5. opencv之获取图片的width和height以及矩形框标注

    获取图片的width和height imread函数读取一张图片时,其返回值为一个矩阵,矩阵的行数代表height,矩阵的列数代表width,不要搞混,也就是shape[0]代表height,shap ...

  6. java中的onresume_android onCreate onResume中获取 View 宽高为0分析

    1.问题测试 xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_par ...

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

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

  8. Android在OnCreate中获取控件的宽度和高度

    在Android中,有时需要对控件进行测量,得到的控件宽度和高度可以用来做一些计算.在需要自适应屏幕的情况下,这种计算就显得特别重要.另一方便,由于需求的原因,希望一进入界面后,就能得到控件的宽度和高 ...

  9. matlab中获取view,ios 怎么获取一个view的位置

    ios 怎么获取一个view的位置以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! ios 怎么获取一个view的位置 打 ...

最新文章

  1. 关闭Windows 7中的 Program Compatibility Assistant
  2. vivo系统如何没root激活Xposed框架的经验
  3. “service httpd does not support chkconfig” 問題
  4. 代码中特殊的注释技术——TODO、FIXME和XXX的用处
  5. VTK:网格之MatrixMathFilter
  6. SAP C4C Mashup port bindingF4帮助对话框里的数据源
  7. 02 李俊杰 20160221-S1笔试
  8. 通过js滚轮滚动时调用动画_WOW.js在页面滚动时展现动感的元素动画效果
  9. 什么是mapDispatchToProps?
  10. 股市最好用的大数据软件_十大股票软件排名谁知道?
  11. 104规约使用总结(一)——格式介绍
  12. 禁止 DELL E5420 触摸板的方法
  13. 机器学习_高偏差(High bias)与高方差(High vars)
  14. 如何区分字母大写I小写字母l以及数字1
  15. 百寸大屏搭配高清画质,极米NEW Z6X轻松打造沉浸式家庭影院
  16. PyQt5在已运行界面中通过Botton按钮触发添加新的Botton按钮
  17. 2021-07-02软件构造学习中遇到的问题
  18. mysql创建零件供应商表_● 建立一个供应商、零件数据库。其中“供应商”表 S(Sno,Sname,Zip,City)分别表示: 供应商代码、 供应 - 赏学吧...
  19. 校招c语言笔试题数组,华为校园招聘考试C语言C笔试题
  20. 我才22岁,我再玩一年又能怎么样?等我23岁的时候,一定给你活出个人样

热门文章

  1. java 面向对象 — 继承
  2. 批量scp脚本——从多台机器拷贝文件
  3. windows网络编程第二版 第三章 Internet Protocol 读书笔记
  4. CPU : Intel CPU命名规则
  5. LeetCode 1004.最长连续1的个数
  6. linux下文件权限管理
  7. 找出1-100中缺失的两个数
  8. 前端工程师必备:学习资源全网罗
  9. 从github克隆内容到本地时权限问题
  10. win10 EFI装ubuntu14.04双系统 及初始配置