1.概要:
Android源代码中很多模块都使用了post()方法,深入理解框架曾运行机制对于避开类似于本例中的小陷阱是很重要的
2.问题提出:
如果开发一些依赖于UI控件的宽和高的功能,开发者可能会用到View的getHeight()和getWidth()方法。试图在Activity的
onCreate()方法中获取控件的宽和高。遗憾的是如果开发者在onCreate()方法中调用上述方法,会发现返回值都是0.
3.解释问题原因:
当onCreate()方法被调用时,会通过LayoutInflater将XML布局文件填充到ContentView。填充过程只包括创建试图,却不包括设置其大小。
那么试图的大小事在何时指定的呢?
Android开发文档的解释如下所示:
绘制布局由两个遍历过程组成:测量过程和布局过程。测量过程由 measure(int, int) 方法完成,该方法从上到下遍历视图
树。在递归遍历过程中,每个视图都会向下层传递尺寸和规格。当measure 方法遍历结束时,每个视图都保存了各自的尺寸信息。第
二个过程由 layout(int, int, int, int) 方法完成,该方法也是由上而下遍历视图树,在遍历过程中,每个父视图通过测量过程的结果定位
所有子视图的位置信息。
4.结论如下:
只有在整个布局绘制完毕后,视图才能得到自身的高和宽,这个过程发生在onCreate()方法之后,因此,在此之前调用getHeight()和getWidth()
方法返回的结果都是0.
5.解决办法:
在UI线程当中去获取, 这就要涉及一个方法post()
代码:
1 public class MainActivity extends Activity { 2 private Button btn; 3 @Override 4 protected void onCreate(Bundle savedInstanceState) { 5 super.onCreate(savedInstanceState); 6 setContentView(R.layout.activity_main); 7 btn = (Button) findViewById(R.id.btn); 8 System.out.println("Button的btn.getWidth()是-->" + btn.getWidth() 9 + " btn.getHeight()是-->>" + btn.getHeight() 10 + " btn.getMeasuredWidth()" + btn.getMeasuredWidth() 11 + " " + btn.getMeasuredHeight()); 12 btn.post(new Runnable() { 13 @Override 14 public void run() { 15 System.out.println("Button的btn.getWidth()是-->" + btn.getWidth() 16 + " btn.getHeight()是-->>" + btn.getHeight() 17 + " btn.getMeasuredWidth()" + btn.getMeasuredWidth() 18 + " " + btn.getMeasuredHeight()); 19 } 20 }); 21 } 22 23 }
打印结果:
可以看到子啊post方法后就获取到View的值了
其实post方法是子线程访问UI线程的方法,这还提供了其他方法访问主线程,如果你想在
子线程当中改变UI线程的界面就可以用以下方法
相关知识参考地址:http://stackoverflow.com/questions/13840007/what-exactly-does-the-post-method-do
- Activity.runOnUiThread(Runnable)
- View.post(Runnable)
- View.postDelayed(Runnable,long)
- Handler