1辞嗡、View的getWidth()和getMeasuredWidth()有什么區(qū)別嗎?
A律胀、賦值時(shí)機(jī)
getMeasureWidth()方法中的值是通過(guò)setMeasuredDimension()方法來(lái)進(jìn)行設(shè)置的润努。
private void setMeasuredDimensionRaw(int measuredWidth, int
measuredHeight) {
mMeasuredWidth = measuredWidth;
mMeasuredHeight = measuredHeight;
mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET;
}
getWidth()方法中的值則是通過(guò)layout(left,top,right,bottom)方法里的一個(gè)setFrame來(lái)進(jìn)行確定left,top,right,bottom 四個(gè)頂點(diǎn)位置,既初始化mLeft,mTop,mRight,mBottom這四個(gè)值,View的四個(gè)頂點(diǎn)一旦確認(rèn) 那么View在父容器中的位置也就確認(rèn)了.
public final int getWidth() {
return mRight - mLeft;
}
getMeasuredWidth() 當(dāng)View繪制流程中的measure流程結(jié)束以后有值,獲取的是View測(cè)量寬度
getWidth() 當(dāng)View繪制流程中的layout流程結(jié)束之后有值,獲取的是View的實(shí)際高度
正常情況下這兩者獲取的值都是相同的迫淹,除非在onMeasure和onLayout過(guò)程之后秘通,在去手動(dòng)調(diào)用measure()這個(gè)方法 去改變對(duì)應(yīng)的數(shù)值,才可能造成兩者值不同.
public class CustomView extends android.support.v7.widget.AppCompatTextView {
public CustomView(Context context) {
this(context, null);
}
public CustomView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right , bottom );
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
measure(0,0);
int measuredWidth = getMeasuredWidth();
int measuredHeight = getMeasuredHeight();
int width = getWidth();
int height = getHeight();
Log.e("Charles2", "measuredWidth==" + measuredWidth + "--measuredHeight==" + measuredHeight);
Log.e("Charles2", "width==" + width + "---height==" + height);
}
打印日志如下 :
12-18 15:22:50.878 17332-17332/com.example.administrator.myapplication E/Charles2: measuredWidth==117--measuredHeight==53
12-18 15:22:50.879 17332-17332/com.example.administrator.myapplication E/Charles2: width==275---height==275
2敛熬、如何在onCreate中拿到View的寬度和高度肺稀?
(1)重寫 onWindowFocusChanged,需要注意的是此方法會(huì)被調(diào)用多次应民。當(dāng)Activity的窗口
得到焦點(diǎn)和失去焦點(diǎn)時(shí)均會(huì)被調(diào)用一次,使用會(huì)頻繁調(diào)用(不推薦)
(2))View.post (new Runnable)
通過(guò)post可以將一個(gè)runnable投遞到消息隊(duì)列中话原,等待Looper調(diào)用次runnable的時(shí)候,View也已經(jīng)初始化好了.
viewById.post(new Runnable() {
@Override
public void run() {
Log.e("Charles2","寬=" + viewById.getWidth() + " --高=="+ viewById.getHeight());
}
});
(3)ViewTreeObserver,比如使用 OnGlobalLayoutListener這個(gè)接口, 當(dāng)View樹的狀態(tài)發(fā)生改變或者View樹的內(nèi)部的View的可見性發(fā)
生改變夕吻。onGlobalLayout方法將被回調(diào),因此可以獲取寬度,但是onGlobalLayout會(huì)被調(diào)用多次.如果使用還必須記得銷毀這個(gè)監(jiān)聽(不推薦)
ViewTreeObserver viewTreeObserver = viewById.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Log.e("Charles2","寬=" + viewById.getWidth() + " --高=="+ viewById.getHeight());
}
});