如何解决在onCreate()中获取View的width和Height为0?
来源:互联网 发布:建筑力学分析软件 编辑:程序博客网 时间:2024/06/02 03:32
当我们动态创建某些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() { @Override public 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() { @Override public void onGlobalLayout() { view.height;//width and height is ready if (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() { @Override public 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) { @Override protected 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?
- 解决在onCreate()过程中获取View的width和Height为0的方法
- Android解决在onCreate()中获取View的width、Height为0的方法
- 解决在onCreate()过程中获取View的width和Height为0的4种方法
- 解决在onCreate()过程中获取View的width和Height为0的4种方法
- 解决在onCreate()过程中获取View的width和Height为0的4种方法
- 解决在onCreate()过程中获取View的width和Height为0的4种方法
- 解决在onCreate()过程中获取View的width和Height为0的4种方法
- 解决在onCreate()过程中获取View的width和Height为0的4种方法
- 解决在onCreate()过程中获取View的width和Height为0的4种方法
- 解决在onCreate()过程中获取View的width和Height为0的4种方法
- 解决在onCreate()过程中获取View的width和Height为0的4种方法
- 解决在onCreate()过程中获取View的width和Height为0的4种方法
- 解决在onCreate()过程中获取View的width和Height为0的4种方法
- 解决在onCreate()过程中获取View的width和Height为0的4种方法
- 解决在onCreate()过程中获取View的width和Height为0的4种方法
- 解决在onCreate()过程中获取View的width和Height为0的几种方法
- 解决在onCreate()过程中获取View的width和Height为0的4种方法
- JAVA之类加载
- 细说JVM系列:JVM介绍
- va_start va_end
- Java Web Servlet.init() for servlet springMVC threw exception解决
- Android 仿IOS3D时间选择器城市选择器
- 如何解决在onCreate()中获取View的width和Height为0?
- hdu 2389 Rain on your Parade(二分匹配Hopcroft-Carp算法模版)
- linux将jboss加入系统服务
- 【线段树】BAPC2014 E Excellent Engineers (Codeforces GYM 100526)
- LightOJ 1006 :Hex-a-bonacci
- Linux学习--gdb调试
- 在Eclipse中设这JVM的堆栈内存
- Linux设置ip地址
- 最近因为项目需要,需要接入友盟的推送,遇到很多问题,记录一下