首页 > 代码库 > getWidth和getMeasuredWidth在何时可以得到正确数值

getWidth和getMeasuredWidth在何时可以得到正确数值

getMeasuredWidth在源码中的解释如下:

    /**
     * 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;
    }

    /**
     * Return the full width measurement information for this view as computed
     * by the most recent call to {@link #measure(int, int)}.  This result is a bit mask
     * as defined by {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
     * This should be used during measurement and layout calculations only. Use
     * {@link #getWidth()} to see how wide a view is after layout.
     *
     * @return The measured width of this view as a bit mask.
     */
    public final int getMeasuredWidthAndState() {
        return mMeasuredWidth;
    }
大致意思也就是说返回最后一次调用onMeasure所测量得到的宽度。


getWidth在源码中返回View的宽度 单位是pixels

/**
     * 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;
    }

写一个Demo测试一下 代码如下:

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		MLinearLayout root = new MLinearLayout(this);
		setContentView(root);
	}
	
	class MLinearLayout extends LinearLayout
	{

		public MLinearLayout(Context context) 
		{
			super(context);
			setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.MATCH_PARENT));
			addView(new MTextView(context));
			Log.i("AAA","LinearLayout MLinearLayout Width:"+getWidth() +" Height:"+getHeight());
			Log.i("AAA","LinearLayout MLinearLayout MeasuredWidth:"+getMeasuredWidth() +" MeasuredHeight:"+getMeasuredHeight());
		}
		
		@Override
		protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
			// TODO Auto-generated method stub
			super.onMeasure(widthMeasureSpec, heightMeasureSpec);
			Log.i("AAA","LinearLayout onMeasure Width:"+getWidth() +" Height:"+getHeight());
			Log.i("AAA","LinearLayout onMeasure MeasuredWidth:"+getMeasuredWidth() +" MeasuredHeight:"+getMeasuredHeight());
		}
		
		@Override
		protected void onLayout(boolean changed, int l, int t, int r, int b) {
			// TODO Auto-generated method stub
			super.onLayout(changed, l, t, r, b);
			Log.i("AAA","LinearLayout onLayout Width:"+getWidth() +" Height:"+getHeight());
			Log.i("AAA","LinearLayout onLayout MeasuredWidth:"+getMeasuredWidth() +" MeasuredHeight:"+getMeasuredHeight());
		}
		
	}
	
	class MTextView extends TextView
	{

		public MTextView(Context context) {
			super(context);
			setLayoutParams(new LayoutParams(200, 300));
			setText("测试");
			Log.i("AAA"," TextView MTextView Width:"+getWidth() +" Height:"+getHeight());
			Log.i("AAA"," TextView MTextView MeasuredWidth:"+getMeasuredWidth() +" MeasuredHeight:"+getMeasuredHeight());
		}
		
		@Override
		protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
			// TODO Auto-generated method stub
			super.onMeasure(widthMeasureSpec, heightMeasureSpec);
			Log.i("AAA"," TextView onMeasure Width:"+getWidth() +" Height:"+getHeight());
			Log.i("AAA"," TextView onMeasure MeasuredWidth:"+getMeasuredWidth() +" MeasuredHeight:"+getMeasuredHeight());
		}
		
		
		@Override
		protected void onLayout(boolean changed, int left, int top, int right,
				int bottom) {
			// TODO Auto-generated method stub
			super.onLayout(changed, left, top, right, bottom);
			Log.i("AAA"," TextView onLayout Width:"+getWidth() +" Height:"+getHeight());
			Log.i("AAA"," TextView onLayout MeasuredWidth:"+getMeasuredWidth() +" MeasuredHeight:"+getMeasuredHeight());
		}
	}
}

运行之后得到的结果如下:

I/AAA     ( 3631):  TextView MTextView Width:0 Height:0
I/AAA     ( 3631):  TextView MTextView MeasuredWidth:0 MeasuredHeight:0
I/AAA     ( 3631): LinearLayout MLinearLayout Width:0 Height:0
I/AAA     ( 3631): LinearLayout MLinearLayout MeasuredWidth:0 MeasuredHeight:0
I/AAA     ( 3631):  TextView onMeasure Width:0 Height:0
I/AAA     ( 3631):  TextView onMeasure MeasuredWidth:200 MeasuredHeight:300
I/AAA     ( 3631): LinearLayout onMeasure Width:0 Height:0
I/AAA     ( 3631): LinearLayout onMeasure MeasuredWidth:1024 MeasuredHeight:502
I/AAA     ( 3631):  TextView onLayout Width:200 Height:300
I/AAA     ( 3631):  TextView onLayout MeasuredWidth:200 MeasuredHeight:300
I/AAA     ( 3631): LinearLayout onLayout Width:1024 Height:502
I/AAA     ( 3631): LinearLayout onLayout MeasuredWidth:1024 MeasuredHeight:502
I/AAA     ( 3631):  TextView onMeasure Width:200 Height:300
I/AAA     ( 3631):  TextView onMeasure MeasuredWidth:200 MeasuredHeight:300
I/AAA     ( 3631): LinearLayout onMeasure Width:1024 Height:502
I/AAA     ( 3631): LinearLayout onMeasure MeasuredWidth:1024 MeasuredHeight:502
I/AAA     ( 3631):  TextView onLayout Width:200 Height:300
I/AAA     ( 3631):  TextView onLayout MeasuredWidth:200 MeasuredHeight:300
I/AAA     ( 3631): LinearLayout onLayout Width:1024 Height:502
I/AAA     ( 3631): LinearLayout onLayout MeasuredWidth:1024 MeasuredHeight:502

结论:

1.在构造方法中无论是getWidth还是getMeasuredWidth都是得不到正确数值的。

2.getMeasuredWidth得到正确数值需要在调用过onMeasure之后。

3.getWidth得到正确数值需要调用过onLayout之后。


VIew的绘制过程:http://www.cnblogs.com/cowboybusy/archive/2012/08/26/2718888.html