现在有一个业务需求,需要在Activity已启动的时候做一个任务,该任务需要获取某个View的宽/高。直接的想法是从Activity的onCreate或者onResume里面去获取这个View的宽/高。但是实际上在onCreate、onStart、onResume中均无法获取正确的宽/高信息。 原因在于View的Measure过程和Activity的生命周期方法不是同步执行的,因此无法保证Activity执行了onCreate、onStart、onResume时某个View已经测量完毕,如果View没有测量完毕,那么获得的宽高就是0。 解决这个问题的方法有四个。 onWindowFocusChanged():当Activity的窗口得到焦点和失去焦点时均会被调用,且会被调用多次。这个方法被调用时,View已经初始化完毕,宽/高已经准备好了,这个时候去获取宽/高是没有问题的。典型的代码如下。 通过post可以将一个runnable投递到一个消息队列的尾部,然后等待Looper调用此runnable的时候,View也已经初始化好了。典型代码如下。 ViewTreeObserver:注册一个观察者来监听视图树,当视图树的布局、视图树的焦点、视图树将要绘制、视图树滚动等发生改变时,ViewTreeObserver都会收到通知,ViewTreeObserver不能被实例化,可以调用View.getViewTreeObserver()来获得。 使用ViewTreeObserver的众多回调可以解决这个问题,比如使用OnGlobalLayoutListener接口,当View树的状态发生改变或者View树内部的View的可见性发生改变,onGlobalLayoutListener方法会被回调。值得注意的是,**伴随着View树状态改变等,onGlobalLayoutListener会被调用多次。**典型代码如下。 通过手动对View进行measure来得到View的宽/高。按照View的LayoutParams来分: 1)match_parent 直接放弃,无法measure出具体的宽/高。原因在于构造此中MeasureSpec需要知道parentSize,即父容器的剩余空间,而此时是无法知道parentSize的。 2)具体数值(dp/px) 以宽高为100px为例子,具体的代码实现如下。 3)wrap_content 具体代码实现如下。 这里的(1<<30)-1,通过分析MeasureSpec可以知道,View的尺寸使用30位二进制表示,在最大化模式下,用最大值(1<<30)-1在理论上是合理的。 参考资料:《Android开发艺术探索》
关于Activity中获取View宽高的那些事
public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus) { int width = view.getMeasureWidth(); int height = view.getMeasureHeight(); } }
protected void onStart() { super.onStart(); view.post(new Runnable() { @Override public void run() { int width = view.getMeasureWidth(); int height = view.getMeasureHeight(); } }) }
protected void onStart() { super.onStart(); ViewTreeObserver observer = view.getViewTreeObserver(); observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @SuppressWarnings("deprecation") @Override public void onGlobalLayout() { view.getViewTreeObserver().removeGlobalOnLayoutListener(this); int width = view.getMeasureWidth(); int height = view.getMeasureHeight(); } }) }
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY); int heightMeasureSpec = MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY); view.measure(widthMeasureSpec, heightMeasureSpec);
int widthMeasureSpec = MeasureSpec.makeMeasureSpec((1<<30) - 1, MeasureSpec.AT_MOST); int heightMeasureSpec = MeasureSpec.makeMeasureSpec((1<<30) - 1, MeasureSpec.AT_MOST); view.measure(widthMeasureSpec, heightMeasureSpec);
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算