前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在 Activity 的 onCreate() 方法中为什么获取 View 的宽和高为0?

在 Activity 的 onCreate() 方法中为什么获取 View 的宽和高为0?

作者头像
codingblock
发布2019-05-25 15:31:42
1.2K0
发布2019-05-25 15:31:42
举报
文章被收录于专栏:CodingBlockCodingBlock

在 Activity 的 onCreate() 方法中为什么获取 View 的宽和高为0 ?

代码语言:javascript
复制
@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如下:

代码语言:javascript
复制
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 的尺寸。

代码语言:javascript
复制
在 Activity 中,当对所有的 View 初始化完毕后,会回调 onWindowFocusChanged() 方法。
代码语言:javascript
复制
/**
 * 方案一
 * 当 View 初始化完毕是回调
 * 当 Activity 每次获取和失去焦点时回调
 * @param hasFocus
 */
@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    getViewSize("onWindowFocusChanged");
}

方法二、使用 View.post() 将任务post到消息队列中,当view初始化完毕后looper会执行任务。

代码语言:javascript
复制
@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 的一些监听接口。

代码语言:javascript
复制
例如:当 View 树的状态或者 View 树内部的 View 的可见性发生改变时,ViewTreeObserver.OnGlobalLayoutListener 接口的 onGlobalLayout() 会被回调,可以在此方法内部获取 View  的尺寸。
代码语言:javascript
复制
@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开发进阶从小工到专家》
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-12-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 在 Activity 的 onCreate() 方法中为什么获取 View 的宽和高为0 ?
  • 方法一、在 Activity 的 onWindowFocusChanged() 方法中获取 View 的尺寸。
  • 方法二、使用 View.post() 将任务post到消息队列中,当view初始化完毕后looper会执行任务。
  • 方法三、可以使用 ViewTreeObserver 的一些监听接口。
相关产品与服务
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档