美文网首页
Activity正确获取View宽高

Activity正确获取View宽高

作者: fomin | 来源:发表于2018-11-01 18:12 被阅读0次

    在View的measure完成后,一般可以通过getMeasureWidth/getMeasureWidth方法可以正确的获取View的宽高,而在特殊情况下,可能需要多次measure才能确定最终的测量宽高,onMeasure无法获取正确的宽高,但可以在onLayout方法中获取测量宽高。

    而在Activity生命周期方法中,是无法通过getMeasureWidth/getMeasureWidth获取正确的测量宽高,是因为View的measure和Activity的生命周期方法不是同步执行的,因此无法保证Activity执行生命周期方法时View已经绘制完毕,如果没有绘制完,宽高可能是0。可以通过以下四种方法解决这个问题:
    1、Acvtivity/View#onWindowFocusChanged

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            int width = view.getMeasuredWidth();
            int height = view.getMeasuredHeight();
        }
    }
    

    需要注意的是,这个方法可能会被调用多次,例如onResume和onPause调用,均会调用这个方法。

    2、view.post(runnable)

    通过post可以将一个runnable投递到消息队列的尾部,等待Looper调用次runnable时候,view已经初始化了。

    view.post(new Runnable() {
        @Override
        public void run() {
            int width = view.getMeasuredWidth();
            int height = view.getMeasuredHeight();
        }
    });
    

    3、ViewTreeObserver

    view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            view.getViewTreeObserver().removeOnGlobalLayoutListener(this::onGlobalLayout);
            int width = view.getMeasuredWidth();
            int height = view.getMeasuredHeight();
        }
    });
    

    需要注意,伴随着View树的状态改变,onGlobalLayout()会被调用多次。

    4、view.measure(int widthMeasureSpec,int heightMeasureSpec)

    通过手动对View进行measure来得到View的宽高,但需要根据不同情况来进行处理

    • match_parent

    这个无法measure具体的宽高,是因为需要知道父容器的parentSize,但这个时候是无法获取的。

    • 具体的数值
    int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY);
    int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY);
    view.measure(widthMeasureSpec, heightMeasureSpec);
    
    • wrap_content
    int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST);
    int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST);
    view.measure(widthMeasureSpec, heightMeasureSpec);
    

    相关文章

      网友评论

          本文标题:Activity正确获取View宽高

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