通過源碼分析View的測量,源碼分析View測量

來源:互聯網
上載者:User

通過源碼分析View的測量,源碼分析View測量

 

要理解View的測量,首先要瞭解MeasureSpec,系統在測量view的寬高時,要先確定MeasureSpec。

MeasureSpec(32為int值)由兩部分組成:

SpecMode(高2位):測量模式。

SpecSize(低30位):某種測量模式下的規格大小。

 

SpecMode有3類:

UNSPECIFIED: 父容器不對view做大小限制,一般用於系統內部,表示一種測量狀態。

EXACTLY:精確模式。對應於:LayoutPrams中的match_parent和具體數值。

AT_MOST:最大值模式。對應於LayoutParam中的wrap_content模式。

 

接下來我們看看View的onMeasure方法:

/**     * <p>     * Measure the view and its content to determine the measured width and the     * measured height. This method is invoked by {@link #measure(int, int)} and     * should be overridden by subclasses to provide accurate and efficient     * measurement of their contents.     * </p>     *protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));    }

該方法是由measure來調用的,view寬高的測量值最終是通過setMeasuredDimension來設定,具體實現不去深究。


我們看看getDefaultSize方法:

/**     * Utility to return a default size. Uses the supplied size if the     * MeasureSpec imposed no constraints. Will get larger if allowed     * by the MeasureSpec.     *     * @param size Default size for this view     * @param measureSpec Constraints imposed by the parent     * @return The size this view should be.     */    public static int getDefaultSize(int size, int measureSpec) {        int result = size;        int specMode = MeasureSpec.getMode(measureSpec);        int specSize = MeasureSpec.getSize(measureSpec);        switch (specMode) {        case MeasureSpec.UNSPECIFIED:            result = size;            break;        case MeasureSpec.AT_MOST:        case MeasureSpec.EXACTLY:            result = specSize;            break;        }        return result;    }

 

先從MeasureSpec中擷取的測量模式specMode和該模式下的大小specSize,然後對測量模式進行判斷,如果是UNSPECIFIED,那麼結果就是參數size,對於這個size是什麼等會討論。如果是AT_MOST和EXACTLY,那麼結果就是view測量後的大小specSize。

那麼這個參數size到底是什麼呢?它是由實參getSuggestedMinimumWidth()和getSuggestedMinimumHeight()傳下來的,我們進去getSuggestedMinimumWidth()看看。

/**     * Returns the suggested minimum width that the view should use. This     * returns the maximum of the view's minimum width)     * and the background's minimum width     *  ({@link android.graphics.drawable.Drawable#getMinimumWidth()}).     * <p>     * When being used in {@link #onMeasure(int, int)}, the caller should still     * ensure the returned width is within the requirements of the parent.     *     * @return The suggested minimum width of the view.     */    protected int getSuggestedMinimumWidth() {        return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());    }

 

從代碼我們可以看出如果該view設定了背景,那麼就返回max(mMinWidth, mBackground.getMinimumWidth()),否則返回mMinWidth。
mMinWidth是什麼呢?它是對應android:minWidth這個屬性的值,若是不指定,那麼預設為0.

max(mMinWidth, mBackground.getMinimumWidth()):返回mMinWidth和mBackground.getMinimumWidth()兩者中的最大值。

mBackground.getMinimumWidth()的代碼如下:

/**     * Returns the minimum width suggested by this Drawable. If a View uses this     * Drawable as a background, it is suggested that the View use at least this     * value for its width. (There will be some scenarios where this will not be     * possible.) This value should INCLUDE any padding.     *     * @return The minimum width suggested by this Drawable. If this Drawable     *         doesn't have a suggested minimum width, 0 is returned.     */    public int getMinimumWidth() {        final int intrinsicWidth = getIntrinsicWidth();        return intrinsicWidth > 0 ? intrinsicWidth : 0;    }


它返回的是Drawable的原始寬度,如果Drawable有原始寬度的話。否則返回0.

 

因此若view有設定背景,那麼size就是android:minWidth和背景最小寬度這兩者的最大值,若沒有設定背景,那麼size的值就是android:minWidth的值。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.