Android查缺补漏(View篇)--在 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知识进行再次梳理,查缺补漏的学习过程,一方面是对自己遗忘的东西加以复习重新掌握,另一方面相信在重新学习的过程中定会有巨大的新收获,如果你也有跟我同样的想法,不妨关注我一起学习,互相探讨,共同进步!
参考文献:
- 《Android开发艺术探索》
 - 《Android开发进阶从小工到专家》
 
Android查缺补漏(View篇)--在 Activity 的 onCreate() 方法中为什么获取 View 的宽和高为0?的更多相关文章
- Android查缺补漏(View篇)--自定义 View 的基本流程
		
View是Android很重要的一部分,常用的View有Button.TextView.EditView.ListView.GridView.各种layout等等,开发者通过对这些View的各种组合以 ...
 - Android查缺补漏(View篇)--事件分发机制源码分析
		
在上一篇博文中分析了事件分发的流程及规则,本篇会从源码的角度更进一步理解事件分发机制的原理,如果对事件分发规则还不太清楚的童鞋,建议先看一下上一篇博文 <Android查缺补漏(View篇)-- ...
 - Android查缺补漏(IPC篇)-- Bundle、文件共享、ContentProvider、Messenger四种进程间通讯介绍
		
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8387752.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...
 - Android查缺补漏(IPC篇)-- 款进程通讯之AIDL详解
		
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8436529.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...
 - Android查缺补漏(线程篇)-- IntentService的源码浅析
		
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8975114.html 在Android中有两个比较容易弄混的概念,Servic ...
 - Android查缺补漏(IPC篇)-- 进程间通讯之AIDL详解
		
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8436529.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...
 - Android查缺补漏(IPC篇)-- 进程间通讯基础知识热身
		
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8479282.html 在Android中进程间通信是比较难的一部分,同时又非常 ...
 - Android查缺补漏(IPC篇)-- 进程间通讯之Socket简介及示例
		
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8425736.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...
 - Android查缺补漏(View篇)--自定义View利器Canvas和Paint详解
		
上篇文章介绍了自定义View的创建流程,从宏观上给出了一个自定义View的创建步骤,本篇是上一篇文章的延续,介绍了自定义View中两个必不可少的工具Canvas和Paint,从细节上更进一步的讲解自定 ...
 
随机推荐
- 【小技巧解决大问题】使用 frp 突破阿里云主机无弹性公网 IP 不能用作 Web 服务器的限制
			
背景 今年 8 月份左右,打折价买了一个阿里云主机,比平常便宜了 2000 多块.买了之后,本想作为一个博客网站的,毕竟国内的服务器访问肯定快一些.满心欢喜的下单之后,却发现 http 服务,外网怎么 ...
 - SpringAware
			
哈哈,终于把分布式的课程演讲给混过去了,下面开始随便自己学点东西. 正题:SpringAware--------在实际项目中,用到spring容器的本省功能资源,这是Bean必须意识到Spring容器 ...
 - (三):C++分布式实时应用框架——系统管理模块
			
C++分布式实时应用框架--系统管理模块 上篇:(二): 基于ZeroMQ的实时通讯平台 一个分布式实时系统集群动辄上百台机器,集群的规模已经限定这将是一个"封闭"的系统.你不可能 ...
 - MS08_067漏洞学习研究
			
p197 MS08-067漏洞渗透攻击 按照书上的设置做,exploit得到错误信息: Exploit failed [unreachable]: Rex::ConnectionRefused The ...
 - 关于Could not resolve dependencies for project
			
异常:Could not resolve dependencies for project 思路:网上提出的方案思路都是把相互依赖的项目导入到本地仓库中. 目前一劳永逸的方法是:将<packag ...
 - 13. ZooKeeper最佳实践
			
以下列举了运行和管理ZooKeeper ensemble的一些最佳实践: ZooKeeper数据目录包含快照和事务日志文件.如果autopurge选项未启用,定期清理目录是一个好习惯.另外,管理员可能 ...
 - 基于Flink秒级计算时CPU监控图表数据中断问题
			
基于Flink进行秒级计算时,发现监控图表中CPU有数据中断现象,通过一段时间的跟踪定位,该问题目前已得到有效解决,以下是解决思路: 一.问题现象 以SQL02为例,发现本来10秒一 ...
 - Mybatis(二)参数(Parameters)传递
			
Mybatis参数(Parameters)传递 1..单个参数 可以接受基本类型,对象类型,集合类型的值.这种情况MyBatis可直接使用这个参数,不需要经过任何处理. <!-- 根据id查询 ...
 - MySql的简单数据类型区别与认识
			
date 3字节,日期,格式:2014-09-18time 3字节,时间,格式:08:42:30datetime 8字节,日期时间,格式:2014-09-18 08:42:30 ...
 - netconf、yang和XML关系
			
netconf是基于xml的网络配置协议,文档RFC6241有详细介绍. yang是为netconf建模的一种数据建模语言.文档RFC2060详细介绍了yang1.0版本,RFC7950介绍了yang ...