android - MeasureSpec中的测量模式和match_parent、wrap_content是什么对应关系?
PHP中文网
PHP中文网 2017-04-17 12:04:07
0
1
640

下面是我的测试程序, 重写了 View 中的 getDefaultSize 方法,打印出每次调用 getDefaultSize 的时候传递进来的 measureSpec 的模式,在主 activity 的 xml 中放了 3 个 TestView,分别使用 wrap_content、match_parent、具体 dp 值,来指定 layout_width 和 layout_height 的值,期望通过 log 看到 3 个 view 在调用自己的 onMeasure 方法的时候传递进来的测量约束的模式。但是打印结果让我很糊涂,因为打印的结果和设置的值看起来并不是一一对应的关系?所以我想问,测量模式和 layout_width 的值的类型是到底什么对应关系?

MainActivity 布局文件如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.testmeasurespec.MainActivity" >

    <com.example.testmeasurespec.TestView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/ic_launcher"
        android:tag="test1" />

    <com.example.testmeasurespec.TestView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/ic_launcher"
        android:tag="test2" />

    <com.example.testmeasurespec.TestView
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:background="@drawable/ic_launcher"
        android:tag="test3" />

</RelativeLayout>

测试 TestView 类如下:

public class TestView extends View {

    private static final String TAG = "TestView";

    public TestView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public TestView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TestView(Context context) {
        super(context);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub
        Log.i(TAG, "onMeasure:" + getTag());
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
    }

    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:
                Log.i(TAG, "specMode:MeasureSpec.UNSPECIFIED");
                result = size;
                break;
            case MeasureSpec.AT_MOST:
                Log.i(TAG, "specMode:MeasureSpec.AT_MOST");
            case MeasureSpec.EXACTLY:
                Log.i(TAG, "specMode:MeasureSpec.EXACTLY");
                result = specSize;
                break;
        }
        return result;
    }
}

打印结果如下:
11-21 16:13:48.812: I/TestView(21213): onMeasure:test3
11-21 16:13:48.812: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.812: I/TestView(21213): specMode:MeasureSpec.AT_MOST
11-21 16:13:48.812: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.812: I/TestView(21213): onMeasure:test2
11-21 16:13:48.812: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.812: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.812: I/TestView(21213): onMeasure:test1
11-21 16:13:48.812: I/TestView(21213): specMode:MeasureSpec.AT_MOST
11-21 16:13:48.812: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.812: I/TestView(21213): specMode:MeasureSpec.AT_MOST
11-21 16:13:48.812: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.812: I/TestView(21213): onMeasure:test3
11-21 16:13:48.812: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.812: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.812: I/TestView(21213): onMeasure:test2
11-21 16:13:48.812: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.812: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.812: I/TestView(21213): onMeasure:test1
11-21 16:13:48.812: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.812: I/TestView(21213): specMode:MeasureSpec.AT_MOST
11-21 16:13:48.812: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.892: I/TestView(21213): onMeasure:test3
11-21 16:13:48.892: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.892: I/TestView(21213): specMode:MeasureSpec.AT_MOST
11-21 16:13:48.892: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.892: I/TestView(21213): onMeasure:test2
11-21 16:13:48.892: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.892: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.902: I/TestView(21213): onMeasure:test1
11-21 16:13:48.902: I/TestView(21213): specMode:MeasureSpec.AT_MOST
11-21 16:13:48.902: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.902: I/TestView(21213): specMode:MeasureSpec.AT_MOST
11-21 16:13:48.902: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.902: I/TestView(21213): onMeasure:test3
11-21 16:13:48.902: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.902: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.902: I/TestView(21213): onMeasure:test2
11-21 16:13:48.902: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.902: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.902: I/TestView(21213): onMeasure:test1
11-21 16:13:48.902: I/TestView(21213): specMode:MeasureSpec.EXACTLY
11-21 16:13:48.902: I/TestView(21213): specMode:MeasureSpec.AT_MOST
11-21 16:13:48.902: I/TestView(21213): specMode:MeasureSpec.EXACTLY

PHP中文网
PHP中文网

认证0级讲师

全部回覆(1)
迷茫

最簡單的映射關係是:
* wrap_parent -> MeasureSpec.AT_MOST
* match_parent -> MeasureSpec.EXACTLY
* 具體值 -> MeasureSpec.EXACTLY

但上面程式碼由於放在RelativeLayout 中,RelativeLayout 是一個比較複雜的ViewGroup,其中子view 的大小不僅跟layout_width、layout_height 屬性相關,還更很多屬性有關係,所以會改變上述映射情況,使結果變得特別複雜。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板