View 的 getWidth 和 getMeasuredWidth() 有什麼區別;
區別問題先看源碼
getMeasuredWidth 的源碼
public static final int MEASURED_SIZE_MASK = 0x00ffffff;
public final int getMeasuredWidth() {
//掩碼只看前兩位後面的
return mMeasuredWidth & MEASURED_SIZE_MASK;
}
private void setMeasuredDimensionRaw(int measuredWidth, int measuredHeight) {
mMeasuredWidth = measuredWidth;
mMeasuredHeight = measuredHeight;
mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET;
}
mMeasuredWidth & MEASURED_SIZE_MASK 獲取後六位,是measure階段結束後 view 的真實值
public final int getWidth() {
return mRight - mLeft;
}
在 layout 階段調用 setOpticalFrame()在調用 setFrame 的方法中設置,表示 view 在頁面中的最終大小
2. 如何在onCreate() 拿到 View 的寬度和高度。
window對象並沒有創建完成只是做了出事貨操作,要獲得控件尺寸要等到控件 onDraw 執行之後,一般通過下面3種方法解決
1. 通過 view 類 getViewTreeObserver 爲控件添加觀察者當獲得正確的寬高後,請移除這個觀察者,否則回調會多次執行
“`
tv.getViewTreeObserver().addOnPreDrawListener(){
public boolean onPreDraw(){
if(!hasDraw){
Log.e(TAG,tv.getMeasuredWidth()+"=="+tv.getMeasuredHeight());
hasDraw =true;
}
return true;
}
}
```
2. 監聽 view 可是狀態變化,view 繪製之後,可是狀態會發生改變添加addOnGlobalLayoutListener來監聽
```
tv.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Log.e(TAG,tv.getMeasuredWidth()+"=="+tv.getMeasuredHeight());
}
});
“`
3. 重新執行一次view 的onMeasure 方法
```
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ImageView imageView = (ImageView) findViewById(R.id.imageview);
//------------------------------------------------方法一
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();
textView.append("\n"+height+","+width);
System.out.println("執行完畢.."+System.currentTimeMillis());
}
“`
第三種會多執行一次onMeasure,第一種要加被重複調用的處理,一般使用第二種方法