獲取View 尺寸理解

  1. 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,第一種要加被重複調用的處理,一般使用第二種方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章