獲取View寬高的四種方式(避免獲取的爲0)

前言

在Activity獲取控件寬高時,有時獲取的爲0,無法獲取正確的信息,原因是View的measure過程和Activity的生命週期不是同步的,也就是說在Activity走了onCreate、onStart、onResume週期後,並不一定View能測繪完成。

解決方式

  1. onWindowFocusChanged方法中做監聽
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus){
            int width = txt.getMeasuredWidth();
            int height = txt.getMeasuredHeight();
            Log.e("測試","onWindowFocusChanged: "+width+"---"+height);
        }
    }

此方法,在Activity失去或者獲取到焦點時,會多次調用。

  1. 採用post方法
//txt是一個view
 txt.post(new Runnable() {
            @Override
            public void run() {
                int width = txt.getMeasuredWidth();
                int height = txt.getMeasuredHeight();
                Log.e("測試","post: "+width+"---"+height);
            }
        });

post將一個Runnable放到消息隊列中,運行在UI線程中,此Runnable所在的隊列,會在view被attached時,進行調用,所以此時,view已經初始化好。

  1. ViewTreeObserver方式
 ViewTreeObserver observer = txt.getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                txt.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                int width = txt.getMeasuredWidth();
                int height = txt.getMeasuredHeight();
                Log.e("測試","ViewTreeObserver: "+width+"---"+height);
            }
        });

當視圖樹的狀態發生改變或者視圖的可見性發生改變,onGlobalLayout將會被回調,此監聽會多次回調,所以要及時註銷監聽。

  1. view.measure(int widthMeasureSpec, int heightMeasureSpec) 手動測量
 private void measuWidthHeight(){
		//具體值
        int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(300, View.MeasureSpec.EXACTLY);
        int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(300, View.MeasureSpec.EXACTLY);
        //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);
        txt.measure(widthMeasureSpec,heightMeasureSpec);

        Log.e("測試","post: "+txt.getMeasuredWidth()+"---"+txt.getMeasuredHeight());
    }

對於match_parent來說,是無法進行測量的,因爲此時無法知道父容器的剩餘空間。

附錄

View的MesaureSpec創建規則表
在這裏插入圖片描述

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