关于View基本知识点

作者: Kael_祈求者 | 来源:发表于2017-12-18 16:01 被阅读0次

1、View的getWidth()和getMeasuredWidth()有什么区别吗?

A、赋值时机
getMeasureWidth()方法中的值是通过setMeasuredDimension()方法来进行设置的。

private void setMeasuredDimensionRaw(int measuredWidth, int 
  measuredHeight) {
        mMeasuredWidth = measuredWidth;
        mMeasuredHeight = measuredHeight;

        mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET;
    }

getWidth()方法中的值则是通过layout(left,top,right,bottom)方法里的一个setFrame来进行确定left,top,right,bottom 四个顶点位置,既初始化mLeft,mTop,mRight,mBottom这四个值,View的四个顶点一旦确认 那么View在父容器中的位置也就确认了.

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

getMeasuredWidth() 当View绘制流程中的measure流程结束以后有值,获取的是View测量宽度
getWidth() 当View绘制流程中的layout流程结束之后有值,获取的是View的实际高度

正常情况下这两者获取的值都是相同的,除非在onMeasure和onLayout过程之后,在去手动调用measure()这个方法 去改变对应的数值,才可能造成两者值不同.

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,需要注意的是此方法会被调用多次。当Activity的窗口
    得到焦点和失去焦点时均会被调用一次,使用会频繁调用(不推荐)

   (2))View.post (new Runnable)
     通过post可以将一个runnable投递到消息队列中,等待Looper调用次runnable的时候,View也已经初始化好了.

        viewById.post(new Runnable() {
            @Override
            public void run() {
                Log.e("Charles2","宽=" + viewById.getWidth() + " --高=="+ viewById.getHeight());
            }
        });

    (3)ViewTreeObserver,比如使用 OnGlobalLayoutListener这个接口, 当View树的状态发生改变或者View树的内部的View的可见性发
        生改变。onGlobalLayout方法将被回调,因此可以获取宽度,但是onGlobalLayout会被调用多次.如果使用还必须记得销毁这个监听(不推荐)

        ViewTreeObserver viewTreeObserver = viewById.getViewTreeObserver();
        viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Log.e("Charles2","宽=" + viewById.getWidth() + " --高=="+ viewById.getHeight());
            }
        });

相关文章

网友评论

    本文标题:关于View基本知识点

    本文链接:https://www.haomeiwen.com/subject/ytmpwxtx.html