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,从细节上更进一步的讲解自定 ...
随机推荐
- R语言高性能编程(三)
一.使用并行计算加倍提升性能1.数据并行 VS 任务并行实现数据并行的算法scoket 并行性注意并行计算时间并不与执行任务的计算资源数目成正比(计算机核心),amdahl定律:并行代码的速度受限于串 ...
- Python的classmethod和staticmethod区别
静态方法(staticmethod) 类方法(classmethod) 静态方法和类方法都可以通过类名.方法名或者实例.方法访问. #-*- coding:utf8 -*- class A(objec ...
- 一致性hash算法以及其在分布式系统中的应用(转)
初始架构
- JavaWeb框架SSH_Struts2_(二)
1. Struts2的核心配置(详解) 本章内容目录: 配置struts.xml文件 struts.xml文件 常量配置 包配置 包含配置 Action配置 实现Action控制类 配置Action ...
- (转载)java 枚举 循环遍历以及一些简单常见的使用
本文转载自:http://blog.csdn.net/qq_27093465/article/details/51706076 作者:李学凯 什么时候想用枚举类型: 有时候,在设计一个java mod ...
- Servlet之初始化参数和传递数据(ServletConfig,ServletContext )
ServletConfig 容器初始化一个Servlet的时候,会为这个Servlet建一个唯一的Servletconfig的对象(Servlet的配置对象) 容器会从部署的描述文件(web.xml) ...
- 已有模板与tp框架结合
具体实现步骤: ①复制模板文件到view指定文件目录: ②复制css.js.img到view指定文件目录: ③把静态资源(css.js.img)文件的路径设置为“常量”信息(在index.php入口文 ...
- OC中只有重写没有重载
一.类的继承 Objective-c中类的继承与C++类似,不同的是Objective-c不支持多重继承,一个类只能有一个父类,单继承使Objective-c的继承关系很简单,易于管理程序. 二.方法 ...
- 逻辑运算&数据
数据在计算机中只是0和1而已 数据在我们的理论中可以无穷大,但是在计算机中并不是,毕竟硬盘是有大小的. 具体可以通过一张图来理解 例如,0-F的表示 上面是有符号数,那么无符号数则是 事实上,计算机中 ...
- ML笔记:Gradient Descent
Review: Gradient Descent Tip 1: Tuning your learning rates eta恰好,可以走到局部最小值点; eta太小,走得太慢,也可以走到局部最小值点; ...