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

在这里插入图片描述

在 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开发,还是已经有一定经验的开发者,亦或是想要进阶和突破20~30K薪资范畴。学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈

如果你没有方向,这里分享一份涵盖了从基本的Android开发到高级知识内容的《Android十大模块进阶笔记》,包括车载开发、UI设计,Android Framework底层原理等方面。这份学习笔记不仅深入浅出,而且非常实用,让大家系统而高效地掌握Android开发的各个知识点

在这里插入图片描述

在这里插入图片描述

相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

另外还有腾讯薪选认证的Android移动架构成长路线图,帮助大家查漏补缺,理顺以后发展路线。

在这里插入图片描述

全套视频资料:

一、面试合集

在这里插入图片描述
二、源码解析合集
在这里插入图片描述

三、开源框架合集
在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取↓↓↓

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值