Android查缺补漏(View篇)--在 Activity 的 onCreate() 方法中为什么获取 View 的宽和高为0?
2017-12-27 22:43
573 查看
在 Activity 的 onCreate() 方法中为什么获取 View 的宽和高为0 ?
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_view); myview = ViewUtils.find(this, R.id.myview); getViewSize("onCreate"); } private void getViewSize(String methodTag) { int width = myview.getWidth(); int height = myview.getHeight(); Log.i(TAG, methodTag + ": width=" + width + " | height=" + height); }
log如下:
12-15 17:04:55.470 29286-29286/cn.codingblock.view I/MyViewActivity: onCreate: width=0 | height=0
如上面代码结果所示,在Activity的onCreate()方法中我们尝试获取控件的宽和高,却获取得是0,这是因为 View 绘制和 Activity 的生命周期方法并不同步,即使 Activity 回调了 onCreate()、onStart()、onResume() 方法,View 也不一定同步完成绘制,所以此时在这些方法里面获取 View 的尺寸时就获取不到,解决方法有以下几种:
方法一、在 Activity 的 onWindowFocusChanged() 方法中获取 View 的尺寸。
在 Activity 中,当对所有的 View 初始化完毕后,会回调 onWindowFocusChanged() 方法。
/** * 方案一 * 当 View 初始化完毕是回调 * 当 Activity 每次获取和失去焦点时回调 * @param hasFocus */ @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); getViewSize("onWindowFocusChanged"); }
方法二、使用 View.post() 将任务post到消息队列中,当view初始化完毕后looper会执行任务。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_view); myview = ViewUtils.find(this, R.id.myview); // 方案二、将任务post到消息队列中,当view初始化完毕后looper会执行任务 myview.post(new Runnable() { @Override public void run() { getViewSize("post"); } }); }
方法三、可以使用 ViewTreeObserver 的一些监听接口。
例如:当 View 树的状态或者 View 树内部的 View 的可见性发生改变时,ViewTreeObserver.OnGlobalLayoutListener 接口的 onGlobalLayout() 会被回调,可以在此方法内部获取 View 的尺寸。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_view); myview = ViewUtils.find(this, R.id.myview); // 方案三、当 View 树的状态或者 View 树内部的 View 的可见性发生改变时, // ViewTreeObserver.OnGlobalLayoutListener 接口的 onGlobalLayout() 会被回调, // 可以在此方法内部获取 View 的尺寸 ViewTreeObserver observer = myview.getViewTreeObserver(); observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { getViewSize("onGlobalLayout"); } }); }
当然除了以上方法之外还会有其他的方法,例如可以使用延时或者在onCreate()方法中手动调用 View 的测量方法,相对而言以上几种方法更为方便。
最后想说的是,本系列文章为博主对Android知识进行再次梳理,查缺补漏的学习过程,一方面是对自己遗忘的东西加以复习重新掌握,另一方面相信在重新学习的过程中定会有巨大的新收获,如果你也有跟我同样的想法,不妨关注我一起学习,互相探讨,共同进步!
参考文献:
《Android开发艺术探索》
《Android开发进阶从小工到专家》
相关文章推荐
- android 在Activity的OnCreate()方法中如何获取view的宽和高
- android onCreate中获取view宽高为0的多种解决方法
- Android Activity为什么要细化出onCreate、onStart、onResume、onPause、onStop、onDesdroy这么多方法让应用去重载?
- 在Activity的onCreate方法中获取View的width和height
- Android Activity为什么要细化出onCreate、onStart、onResume、onPause、onStop、onDesdroy这么多方法让应用去重载?
- Android在onCreate方法中获取view的宽高
- Android下在onCreate方法中获取TextView的高度
- Android解决在onCreate()中获取View的width、Height为0的方法
- android在onCreate()方法中获取View的宽度与高度的方法实战
- Android在onCreate()方法中动态获取TextView控件的高度
- Android Activity为什么要细化出onCreate、onStart、onResume、onPause、onStop、onDesdroy这么多方法让应用去重载?
- android onCreate中获取view宽高为0的解决方法
- [Android]在onCreate方法中中获取View的宽和高
- android在onCreate()方法中获取View的宽度与高度的方法实战
- Android中一个Activity第二次启动时,onCreate()调用setContentView()方法时出错,程序崩溃
- Android中通过view方式获取当前Activity的屏幕截图实现方法
- 【Android 非人为操作的UI更新】在onCreate()和onResume()等方法中的更新UI操作方法及获取View的相关消息
- Android Activity为什么要细化出onCreate、onStart、onResume、onPause、onStop、onDesdroy这么多方法让应用去重载?
- Android Activity为什么要细化出onCreate、onStart、onResume、onPause、onStop、onDesdroy这么多方法让应用去重载?(转)
- 如何在activity的onCreate方法中获取某个view的高度或宽度