在渲染前获取 View 的宽高

这是一个比较有意义的问题,或者说有难度的问题,问题的背景为:有时候我们需要在view渲染前去获取其宽高,典型的情形是,我们想在onCreate、onStart、onResume中去获取view的宽高。如果大家尝试过,会发现,这个时候view还没有measure好,宽高都为0,那到底该怎么做才能正确获取其宽高呢,下面给出三种方法(还有其他方法, 比如监听器回调等):

Activity/View#onWindowFocusChanged :这个方法表明,view已经初始化完毕了,宽高已经准备好了
view.post(runnable) :通过post可以将一个runnable投递到消息队列的尾部,然后等待looper调用此runnable的时候,view也已经初始化好了
view.measure(int widthMeasureSpec, int heightMeasureSpec) :通过手动去measure来视图得到view的宽高

前两种方法都比较好理解也比较简单,这里主要介绍下第三种方法的详细用法:

采用 view.measure 去提前获取 view 的宽高,根据 view 的 layoutParams 来分
1,match_parent
直接放弃,无法 measure 出具体的宽高
2,具体的数值( dp/px )
比如宽高都是 100px ,如下 measure :
    int widthMeasureSpec = MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY);
    int heightMeasureSpec = MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY);
    view.measure(widthMeasureSpec, heightMeasureSpec);
3,wrap_content
如下 measure :
    int widthMeasureSpec = MeasureSpec.makeMeasureSpec( (1 << 30) - 1, MeasureSpec.AT_MOST);
    int heightMeasureSpec = MeasureSpec.makeMeasureSpec( (1 << 30) - 1, MeasureSpec.AT_MOST);
    view.measure(widthMeasureSpec, heightMeasureSpec);

注意到(1 << 30) - 1,通过分析MeasureSpec的实现可以知道,view的尺寸使用30位二进制表示的,也就是说最大是30个1即 2^30 - 1,也就是(1 << 30) - 1,在最大化模式下,我们用view理论上能支持的最大值去构造MeasureSpec是合理的。

关于view的measure,网络上有两个错误的用法,如下,为什么说是错误的,首先违背了系统的内部实现规范(因为无法通过错误的MeasureSpec去得出合法的SpecMode从而导致measure出错),其次不能保证一定能 measure 出正确的结果。

第一种错误用法
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(-1, MeasureSpec.UNSPECIFIED);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(-1, MeasureSpec.UNSPECIFIED);
view.measure(widthMeasureSpec, heightMeasureSpec);

第二种错误用法
view.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)

在渲染前获取 View 的宽高的更多相关文章

  1. 用addOnGlobalLayoutListener获取View的宽高

    首先,我们在onCreate方法里调用getHeight()和 getWidth()是不能正确获取View的宽高的,因为onCreate方法执行完了,我们定义的控件才会被onMeasure()度量,所 ...

  2. 监听视图树 ViewTreeObserver 获取View的宽高

    前奏:在哪里可以获取到View的宽高 我们知道,在onCreate方法执行完毕以后,View才开始被测量,所以我们在onCreate方法里面通过view.getWidth()或view.getMeas ...

  3. 通过View.post()获取View的宽高

    在Android里,获取View宽高的时机是个老生常谈的话题了.众所周知,在Oncreate里直接调用View.getWidth或者View.getMeasuredWidth返回都是0.所以获取宽高时 ...

  4. Android查缺补漏(View篇)--在 Activity 的 onCreate() 方法中为什么获取 View 的宽和高为0?

    在 Activity 的 onCreate() 方法中为什么获取 View 的宽和高为0 ? @Override protected void onCreate(Bundle savedInstanc ...

  5. js获取隐藏元素宽高的方法

    网上有一些js获取隐藏元素宽高的方法,但是可能会存在某些情况获取不了. 例如: <!DOCTYPE html> <html lang="en"> <h ...

  6. 前端 JS 获取 Image 图像 宽高 尺寸

    前端 JS 获取 Image 图像 宽高 尺寸 简介 项目中用到获取图片的原始尺寸,然后适配宽高:网上的大部分前端解决方案,都是new Image()后,在onload事件中获取image的尺寸. 在 ...

  7. js判断图片加载完成后获取图片实际宽高

    通常,我们会用jq的.width()/.height()方法获取图片的宽度/高度或者用js的.offsetwidth/.offsetheight方法来获取图片的宽度/高度,但这些方法在我们通过样式设置 ...

  8. RT/Metro商店应用如何如何获取图片的宽高

    RT/Metro商店应用如何如何获取图片的宽高 var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms ...

  9. JS获取图片实际宽高及根据图片大小进行自适应

    JS获取图片实际宽高,以及根据图片大小进行自适应  <img src="http://xxx.jpg" id="imgs" onload="ad ...

随机推荐

  1. PHP魔术常量

    与J2E相比PHP没有九个内置对象,但他有八个魔术变量分别是: '__LINE__' 文件中的当前行号. '__FILE__ 文件的完整路径和文件名. '__DIR__' 文件所在的目录. '__FU ...

  2. IOS开发基础知识--碎片47

    1:解决ios静态库中的类别(category)在工程中不能使用 解决方法为:找到 target 的图标,更改其 Other Linker Flags 为: -all_load 或 -force_lo ...

  3. iOS程序破解——class-dump获取头文件

    原文在此:http://www.cnblogs.com/mddblog/p/4942894.html 一.简述 class-dump顾名思义,是用来dump目标对象class信息的工具.它根据oc的r ...

  4. Reveal1.5破解,iOS_UI调试利器Reveal最新版本破解方法

    Reveal1.0.7破解 1.官网下载最新版Reveal,拖动应用程序中,运行一次2.下载16进制编辑器"0xED" for mac(http://dl.vmall.com/c0 ...

  5. java入门知识点结构

    第一部分    计算机程序和面向对象编程 编程语言种类: 机器语言:2进制(0和1) 汇编语言:英文字符缩写和助记符 高级语言: 面向过程:面向过程是从微观上/细节上处理具体事务. C语言 面向对象: ...

  6. ORACLE外部表总结

    外部表介绍 ORACLE外部表用来存取数据库以外的文本文件(Text File)或ORACLE专属格式文件.因此,建立外部表时不会产生段.区.数据块等存储结构,只有与表相关的定义放在数据字典中.外部表 ...

  7. SQL Server 2008 R2的发布订阅配置实践

    纸上得来终觉浅,绝知此事要躬行.搞技术尤其如此,看别人配置SQL SERVER的复制,发布-订阅.镜像.日志传送者方面的文章,感觉挺简单,好像轻轻松松的,但是当你自己去实践的时候,你会发现还真不是那么 ...

  8. Windows7开机登录界面背景图修改

    首先,准备一张文件大小不超过250K的.jpg格式图片,文件名为:BackgroundDefault,图片分辨率建议与屏幕分辨率一致,因为这张背景无法像壁纸一样拉伸或者填充的. 打开这个路径,[C:\ ...

  9. 《The Elder Scrolls V: Skyrim》百般冷门却强力职业

    <The Elder Scrolls V: Skyrim>百般冷门却强力职业 1.有如成龙平常的杂耍型战斗窃贼 每次看帖都察觉大伙一贯在强调窃贼不需要防御,窃贼不需要血,窃贼就是一击致命, ...

  10. loadrnner添加C语言代码的几种方式

    今天有人在群里问,想直接把自己的C语言代码让lr调用,该怎么搞. 这东西说来简单,只是对Loadrunner这工具不熟悉可能才会有这种问题吧.个人理解,一般有三种方法吧,废话不多,直接干货. 1.直接 ...