解决在onCreate()过程中获取View的width和Height为0的4种方法
1、监听Draw/Layout事件:ViewTreeObserver
ViewTreeObserver监听非常多不同的界面绘制事件。一般来说OnGlobalLayoutListener就是能够让我们获得到view的width和height的地方.以下onGlobalLayout内的代码会在View完毕Layout过程后调用。
1 view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 2 @Override 3 public void onGlobalLayout() { 4 mScrollView.post(new Runnable() { 5 public void run() { 6 view.getHeight(); //height is ready 7 } 8 }); 9 } 10 });
可是要注意这种方法在每次有些view的Layout发生变化的时候被调用(比方某个View被设置为Invisible),所以在得到你想要的宽高后,记得移除onGlobleLayoutListener:
在 SDK Lvl < 16时使用
public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)在 SDK Lvl >= 16时使用
public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)
2、将一个runnable加入到Layout队列中:View.post()
这个解决方式是我最喜欢的,可是差点儿没人知道有这种方法。
简单地说。仅仅要用View.post()一个runnable就能够了。runnable对象中的方法会在View的measure、layout等事件后触发,详细的參考Romain Guy:
UI事件队列会按顺序处理事件。
在setContentView()被调用后,事件队列中会包括一个要求又一次layout的message,所以不论什么你post到队列中的东西都会在Layout发生变化后运行。
1 final View view=//smth; 2 ... 3 view.post(new Runnable() { 4 @Override 5 public void run() { 6 view.getHeight(); //height is ready 7 } 8 });
这种方法比ViewTreeObserver好:
1、你的代码仅仅会运行一次。并且你不用在在每次运行后将Observer禁用,省心多了。
2、语法非常easy
參考:
http://stackoverflow.com/a/3602144/774398
http://stackoverflow.com/a/3948036/774398
3、重写View的onLayout方法
这种方法仅仅在某些场景中有用,比方当你所要运行的东西应该作为他的内在逻辑被内聚、模块化在view中,否者这个解决方式就显得十分冗长和笨重。
1 view = new View(this) { 2 @Override 3 protected void onLayout(boolean changed, int l, int t, int r, int b) { 4 super.onLayout(changed, l, t, r, b); 5 view.getHeight(); //height is ready 6 } 7 };
须要注意的是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获得。