在渲染前获取 View 的宽高

在渲染前获取 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)

时间: 2024-08-05 00:13:20

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

在onload事件前获取图片的宽高

有时候在获取从后台的图片时,要对图片进行一系列的处理,才渲染出来 我们要解决的是没有缓存而又快速的相比onload更快的方式去获取图片的宽高,接下来上代码 通过定时循环检测获取: // 记录当前时间戳 var start_time = new Date().getTime() // 图片地址 后面加时间戳是为了避免缓存 var cutSrc = window.ctx + '/touchsys/terminal/showCapture?terminalId=' + terminalId + '×t

android——获取view的宽高

在activity生命周期方法:onCreate(),onStart(),onResume()中调用View.getWidth()和View.getHeight()方法获取View的高度是不可行的,因为此时布局没有加载是不可见状态. 还有当view的可见状态为:GONE,时获取的宽高也是0: 2. 解决办法: (1)直接测量: private void first() { int width = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSp

获取View的宽高的三种方法

来自为知笔记(Wiz)

android获取控件宽高和屏幕宽高

一.获取屏幕宽高 1.android界面简单介绍 要获取屏幕宽高,我们可以先从android的界面构成了解 android的界面主要由三部分构成:1.状态栏 2.标题栏 3.内容区域 \ (1)状态栏 状态栏主要用来显示一些系统图标,应用的通知图标和系统时间. (2)标题栏 android中标题栏主要用来显示当前位置,3.0过后添加了ActionBar,拥有了导航和OptionMenu的功能,5.0又新添加了ToolBar控件,和ActionBar类似,但自定义的空间更充足 (3)内容区域 an

在onCreate()中获取某个View的宽高

我们都知道,在Activity的onCreate()方法中调用View的getWidth()和getHeight()方法时,返回的值都是0,因为Activity调用setContentView方法只是创建了这个View,调用了这个View构造方法而已,其中的onMeasure()方法还没被调用,所以不能知道它的宽高.但是,View有一个公开的方法post(),允许我们通过参数Runnable,在子线程中获取View的宽和高. public class MainActivity extends A

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("onCr

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

网上有一些js获取隐藏元素宽高的方法,但是可能会存在某些情况获取不了. 例如: <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title>test</title> </head> <bo

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

前端 JS 获取 Image 图像 宽高 尺寸 简介 项目中用到获取图片的原始尺寸,然后适配宽高:网上的大部分前端解决方案,都是new Image()后,在onload事件中获取image的尺寸. 在图片数量较多的时候,这样的获取效率实在是低下.所有就有了这篇文章.通过直接读取解析文件的字节码来获取图片的尺寸. IMAGE_HEAD_SIGS var IMAGE_HEAD_SIGS = { GIF: [0x47, 0x49, 0x46], //'G' 'I' 'F' ascii PNG: [0x

根据图片的链接获取图片的宽高

//根据图片的链接获取图片的宽高 - (CGSize)downloadImageSizeWithURL:(id)imageURL { NSURL *URL = nil; if([imageURL isKindOfClass:[NSURL class]]){ URL = imageURL; } if([imageURL isKindOfClass:[NSString class]]){ URL = [NSURL URLWithString:imageURL]; } if(URL == nil) r