<ProgressBar
android:id="@+id/pb_number"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="25dp"
/>
再看看我们得到的值:
方法一
width630px
MeasuredWidth630px
Height50px
MeasuredHeight50px
方法2
postwidth630px
postMeasuredWidth630px
postHeight50px
postMeasuredHeight50px
先说下getWidth和getMeasuredWidth的区别以及两者的使用场景
首先,看getWidth()的官方说明:
public final int getWidth ()
Added in API level 1
Return the width of the your view.
Returns
The width of your view, in pixels.
返回view的宽度,说的不详细,再看getWidth源码:
-
Return the width of the your view.
-
@return The width of your view, in pixels.
*/
@ViewDebug.ExportedProperty(category = “layout”)
public final int getWidth() {
return mRight - mLeft;
}
-
从源码可以看出,getwidth返回的是右边坐标减去左边坐标,这要在布局之后才能确定它们的坐标,也就是说在布局后才能调用getwidth来获取。所以getWidth()获得的宽度是View在设定好布局后整个View的宽度。
> 而对于getmeasuredwidth,我们看看官方解释
public final int getMeasuredWidthAndState ()
Added in API level 11
Return the full width measurement information for this view as computed by the most recent call to measure(int, int). This result is a bit mask as defined byMEASURED_SIZE_MASK and MEASURED_STATE_TOO_SMALL. This should be used during measurement and layout calculations only. Use getWidth() to see how wide a view is after layout.
Returns
The measured width of this view as a bit mask.
得到的是最近一次调用measure()方法测量后得到的是View的宽度,它应该仅仅用在测量和Layout的计算中。再看源码:
/**
-
Like {@link #getMeasuredWidthAndState()}, but only returns the
-
raw width component (that is the result is masked by
-
{@link #MEASURED_SIZE_MASK}).
-
@return The raw measured width of this view.
*/
public final int getMeasuredWidth() {
return mMeasuredWidth & MEASURED_SIZE_MASK;
}
获得的是原始的测量宽度。所以说getMeasuredWidth()是对View上的内容进行测量后得到的View内容占据的宽度。
前提是你必须在父布局的onLayout()方法或者此View的onDraw()方法里调用measure(0,0);(measure中的参数的值你自己可以定义),否则你得到的结果和getWidth()得到的结果是一样的。
> 两者的使用场合:
getMeasuredWidth:
在自定义view重写onLayout时、在我们用layoutinflater动态加载view后想获得view的原始宽度时。
getWidth:
一般在view已经布局后呈现出来了,想获取宽度时
摘自:[http://blog.youkuaiyun.com/u011494050/article/details/39134161]( )
> 下面具体说说几种获取的方式吧:
No1:
int w = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
imageView.measure(w, h);
int height = imageView.getMeasuredHeight();
int width = imageView.getMeasuredWidth();
这种方法很简单,就是我们自己来测量
No2:
ViewTreeObserver vto = imageView.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
vto.removeOnPreDrawListener(this);
int height = imageView.getMeasuredHeight();
int width = imageView.getMeasuredWidth();
return true;
}
});
这个方法,我们需要注册一个ViewTreeObserver的监听回调,这个监听回调,就是专门监听绘图的,既然是监听绘图,那么我们自然可以获取测量值了,同时,我们在每次监听前remove前一次的监听,避免重复监听。
No3:
ViewTreeObserver vto = imageView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
imageView.getHeight();
imageView.getWidth();
}
});
> 这个方法于第2个方法基本相同,但他是全局的布局改变监听器,所以是最推荐使用的。
>
> 总结:那么需要获取控件的宽高该用那个方法呢?
* 方法一: 比其他的两个方法多了一次计算,也就是多调用了一次onMeasure()方法,该方法虽然看上去简单,但是如果要目标控件计算耗时比较大的话(如listView等),不建议使用.
* 方法二:它的回调方法会调用很多次,并且滑动TextView的时候任然会调用,所以不建议使用.
* 方法三:比较合适.
当然,实际应用的时候需要根据实际情况而定.
> 再拓展一种比较简单的方法view.post:
pbNumber.post(new Runnable() {
@Override
public void run() {
Log.v("tag", "postwidth"+pbNumber.getWidth()+"px");
Log.v("tag", "postMeasuredWidth"+pbNumber.getMeasuredWidth()+"px");
Log.v("tag", "postHeight"+pbNumber.getHeight()+"px");
Log.v("tag", "postMeasuredHeight"+pbNumber.getMeasuredHeight()+"px");
}
});
> View.post()这个方法一般用来做什么?
我体会最深的有两个作用:
* 大家都知道在onCreate()方法中调用view.getHeight()会返回0,但是你可以在
view.post(new Runnable() {
@Override