getWidth( )和getMeasuredWith( )

返回值的来源

1、getMeasuredWidth()
getMeasuredWidth() 的取值最终来源于 setMeasuredDimension() 方法调用时传递的参数!在自定义 View 时测量并设置 View 宽高时经常用到,通常在 onMeasure() 方法中最后一步调用它。
2、getWidth( )
getWidth() 的取值最终来源于 layout() 方法的调用。通常,layout() 方法在 parent 中被调用,来确定 child 在父容器中的位置,一般在自定义 ViewGroup 的 onLayout() 方法中调用。

public final int getWidth() {
    return mRight - mLeft;
}

mRight、mLeft 在setFrame() 方法中赋值。

protected boolean setFrame(int left, int top, int right, int bottom) {
        ...
        mLeft = left;
        mTop = top;
        mRight = right;
        mBottom = bottom;
        ...
}

setFrame() 方法在layout() 方法中被调用。

使用注意事项

1、以TextView为例子,在onCreate中由于view可能尚未测量、绘制、布局完成,会导致getWidth( )和getMeasuredWith( )获取到的都是0。
可以在以下函数中获取,就不会是0 了。此时,view已经完成布局、测量、绘制等流程了。

@Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        Log.i("width   onWindowFocus",tvHello.getWidth()+"");
        Log.i("width   onWindowFocus",tvHello.getMeasuredWidth()+"");
    }

2、如果我在onCreate中给TextView 设值之后,偏偏想要获取一下他的宽度该怎么获取呢?
由于我们已经知道了getMeasuredWith( )获取的是measure()之后的值那么我们就先调用下他的measure()函数不就行了吗?
比如:

        tvHello.setText("这里很长哦很长哦很长哦");
        tvHello.setSingleLine(true);
        tvHello.measure(View.MeasureSpec.UNSPECIFIED,View.MeasureSpec.UNSPECIFIED);
        Log.i("width",tvHello.getMeasuredWidth()+"");

我在一家公司实习的时候,由于需要动态地判断一个TextView 赋值之后的宽度,利用这个知识点我解决了这个问题。(一开始我一直用getWidth(),然后一直获取到的都是0,一脸懵逼)。
3、还有通过 OnGlobalLayoutListener 来获取宽度

tvHello.setText("这里很长哦很长哦很长哦");
tvHello.setSingleLine(true);
tvHello.getViewTreeObserver().addOnGlobalLayoutListener(new                  ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Log.i("width onGlobalLayout",tvHello.getWidth()+"");
                if (Build.VERSION.SDK_INT >= 16) {
                    tvHello.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                }else {
                    tvHello.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                }
            }
        });

千万注意:要在onGlobalLayout()中最终移除监听器,避免后续每一次发生全局 View 变化均触发该事件,影响性能。

你可能感兴趣的:(Android_View)