转载请注明出处:http://blog.csdn.net/woshizisezise/article/details/52934227

大家好,这篇博文主要是教给大家一个方法,如何在onCreate()方法中获取我们所需的View对象的高度和宽度,大家应该都试验过,在onCreate()方法中通过view.getWidth()方法和view.getHeight()方法得到的结果都是0,那么这是为什么呢?

因为当onCreate()方法被调用时,会调用LayoutInflater将布局文件填充到ContentView。填充过程只包括创建视图,却不包括设置其大小。那么,视图的大小在什么时候指定的呢?

android开发文档的解释如下:

”绘制由两个遍历过程组成:测量过程和布局过程。测量过程由measure(int,int)方法完成,该方法从上到下遍历视图树。在递归遍历过程中,每个视图都会向下层传递尺寸和规格。当measure方法遍历完成时,每个视图都保存了各自的尺寸信息。第二个过程由layout(int,int,int,int)方法完成,该方法也是从上到下遍历视图树,在遍历过程中,每个父视图通过测量过程的结果定位所有子视图的位置信息。“

  • 结论如下:

只有在整个布局绘制完成后,视图才能得到自身的宽和高,这个过程发生在onCreate()方法之后,因此,在此之前调用getWidth()和getHeight()方法返回的结果都是0。


那么我们怎么在onCreate()方法中得到view的宽和高呢?

当然我们是有方法的,那就是通过View的post()方法解决上述问题,该方法接收一个Runnable线程参数,并将其添加到消息队列中,有趣的是Runnable线程会在UI线程中执行。

示例代码和运行log结果如下所示:

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mTextView = (TextView) findViewById(R.id.main_clock_time);
Log.e(TAG, "mtextview width is : "+mTextView.getWidth()+", height is : "+mTextView.getHeight() );
mTextView.post(new Runnable() {
@Override
public void run() {
Log.e(TAG, "mtextview width is : "+mTextView.getWidth()+", height is : "+mTextView.getHeight() );
}
});
}

运行结果:

10-26 14:10:40.109 11697-11697/? E/MainActivity: mtextview width is : 0, height is : 0
10-26 14:10:40.149 11697-11697/? E/MainActivity: mtextview width is : 872, height is : 211

可以看到在post方法之前获取到的结果值如我们之前提到的都是0,但是通过post()方法运行在线程中的就能正确的获取到宽和高了。

那我就当然点进去看了看源码咯,View.java中的post()方法源码如下:

public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}

// Postpone the runnable until we know on which thread it needs to run.
// Assume that the runnable will be successfully placed after attach.
getRunQueue().post(action);
return true;
}

然后再进入到post(action)方法中,进入到了HandlerActionQueue.java源码中,可以看到post方法源码如下:

public void post(Runnable action) {
postDelayed(action, 0);
}

public void postDelayed(Runnable action, long delayMillis) {
final HandlerAction handlerAction = new HandlerAction(action, delayMillis);

synchronized (this) {
if (mActions == null) {
mActions = new HandlerAction[4];
}
mActions = GrowingArrayUtils.append(mActions, mCount, handlerAction);
mCount++;
}
}

可以看到代码也是做了postDelay的处理延时发送消息,所以这才是能正确的获取到宽和高的终极地方了吧。


如果你觉得我的文章对你有帮助,并且希望帮助更多人,欢迎分享并关注我的微信公众号“Android开发的奥秘”,或扫描识别下方的二维码,我会不定期的分享给大家更多有用的资讯,谢谢!

更多相关文章

  1. W/System.err:at java.net.PlainDatagramSocketImpl.bind(PlainDa
  2. Android Studio获取数字签名(SHA1)的方法
  3. Android Volley:使用方法总结及实例解析
  4. eclipse下运行EasyAR官方sample的方法
  5. Android App性能信息获取方法
  6. Android Studio 检测内存泄漏与解决方法
  7. C#/Java 调用WSDL接口及方法
  8. Javadoc转换chm帮助文档的四种方法总结
  9. 最新Eclipse配置Android开发环境SDK 并安装JellyBean 4.3的方法

随机推荐

  1. android studio打开react-native的androi
  2. Android(安卓)ViewPager与子控件点击事件
  3. Android学习札记15:对Android中View绘制流
  4. Android的Activity and Task Design
  5. Android 提供的一系列辅助系统开发工具
  6. Android(安卓)获取验证码倒计时实现
  7. Android本地数据存储之SQLite
  8. android UI学习书籍
  9. [置顶] Android(安卓)IPC 通讯机制源码分
  10. 我的android 第10天 - pull解析Xml文档