關於View的測量

MeasureSpec類

MeasureSpec類是一個32位的int值(使用位運算是爲了提高並優化效率),高2位是測量模式,低30位是測量大小。

測量模式:

  • EXACTLY(精確模式):
    當把View設置成match_parent時或設置具體的大小時,容器傳入的即是EXACTLY模式

  • AT_MOST(最大值模式):
    源碼可以看出:

    final boolean isWrapContentWidth = widthMode != MeasureSpec.EXACTLY;
        final boolean isWrapContentHeight = heightMode != MeasureSpec.EXACTLY; 

    當把View設置成wrap_content時,容器傳入的是AT_MOST模式。注意的是,自定義View時,需要取出我們制定的大小和specSize中最小的一個來作最後的測量值。如果自定義View時制定了wrap_content屬性,但是沒有重寫onMeasure()方法,系統不知道該使用默認多大的尺寸,因此會默認填滿整個父佈局。

  • UNSPECIFIED:
    不指定大小的測量模式,View想多大就多大(很少見)

onMeasure() sample:

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
    }

measureWidth() Sample:

private int measureWidth(int measureSpec){
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if(specMode == MeasureSpec.EXACTLY){
            result = specSize;
        }else {
            result = 200;
            if(specMode == MeasureSpec.AT_MOST){
                result = Math.min(result, specSize);
            }
        }

        return result;
    }

NOTE:

onMeasure()方法中的widthMeasureSpec和heightMeasureSpec是由父視圖經過計算後傳進來的

發佈了36 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章