为什么不是每个人都使用 ViewGroup.LayoutParams 而不是 LinearLayout.LayoutParams?

Why don't everybody use ViewGroup.LayoutParams instead of LinearLayout.LayoutParams?

因为它可以与 RelativeLinear 布局一起使用。因此,如果我们稍后从 RelativeLayout 更改为 LinearLayout,它可能会很有用。

而且 LinearLayout.LayoutParams 似乎不是 ViewGroup.LayoutParams 的继承函数。

那么我们有什么理由应该使用 LinearLayout.LayoutParams 而不是另一个?使用这个 LinearLayout.LayoutParams 比普通的布局类型有什么特定的优势吗?

So is there any reason we should use LinearLayout.LayoutParams over the other one

LinearLayout 期望 LinearLayout.LayoutParams,正如您通过阅读 the source code for LinearLayout 可以看到的那样。如果您提供其他内容,例如 ViewGroup.LayoutParams,当 LinearLayout 代码尝试将 ViewGroup.LayoutParams 转换为 LinearLayout.LayoutParams 时,您将在运行时使用 ClassCastException 崩溃。

LinearLayout需要使用LinearLayout.LayoutParams,RelativeLayout需要使用RelativeLayout.LayoutParams,否则会崩溃。虽然 MATCH_PARENTWRAP_CONTENT 的常量相同,但特定的布局参数会向布局参数添加额外的信息,例如在 RelativeLayout 中,RelativeLayout.LayoutParams 存储规则你指定为 centerInParentbelowtoRightOf 等。如果你给它一个 LinearLayout.LayoutParams,它就会崩溃。

比如这是LinearLayout.LayoutParams

    public static class LayoutParams extends ViewGroup.MarginLayoutParams {
        @ViewDebug.ExportedProperty(category = "layout")
        public float weight;

这是RelativeLayout.LayoutParams

public static class LayoutParams extends ViewGroup.MarginLayoutParams {
        @ViewDebug.ExportedProperty(category = "layout", resolveId = true, indexMapping = {
            @ViewDebug.IntToString(from = ABOVE,               to = "above"),
            @ViewDebug.IntToString(from = ALIGN_BASELINE,      to = "alignBaseline"),
            @ViewDebug.IntToString(from = ALIGN_BOTTOM,        to = "alignBottom"),
            @ViewDebug.IntToString(from = ALIGN_LEFT,          to = "alignLeft"),
            @ViewDebug.IntToString(from = ALIGN_PARENT_BOTTOM, to = "alignParentBottom"),
            @ViewDebug.IntToString(from = ALIGN_PARENT_LEFT,   to = "alignParentLeft"),
            @ViewDebug.IntToString(from = ALIGN_PARENT_RIGHT,  to = "alignParentRight"),
            @ViewDebug.IntToString(from = ALIGN_PARENT_TOP,    to = "alignParentTop"),
            @ViewDebug.IntToString(from = ALIGN_RIGHT,         to = "alignRight"),
            @ViewDebug.IntToString(from = ALIGN_TOP,           to = "alignTop"),
            @ViewDebug.IntToString(from = BELOW,               to = "below"),
            @ViewDebug.IntToString(from = CENTER_HORIZONTAL,   to = "centerHorizontal"),
            @ViewDebug.IntToString(from = CENTER_IN_PARENT,    to = "center"),
            @ViewDebug.IntToString(from = CENTER_VERTICAL,     to = "centerVertical"),
            @ViewDebug.IntToString(from = LEFT_OF,             to = "leftOf"),
            @ViewDebug.IntToString(from = RIGHT_OF,            to = "rightOf"),
            @ViewDebug.IntToString(from = ALIGN_START,         to = "alignStart"),
            @ViewDebug.IntToString(from = ALIGN_END,           to = "alignEnd"),
            @ViewDebug.IntToString(from = ALIGN_PARENT_START,  to = "alignParentStart"),
            @ViewDebug.IntToString(from = ALIGN_PARENT_END,    to = "alignParentEnd"),
            @ViewDebug.IntToString(from = START_OF,            to = "startOf"),
            @ViewDebug.IntToString(from = END_OF,              to = "endOf")
        }, mapping = {
            @ViewDebug.IntToString(from = TRUE, to = "true"),
            @ViewDebug.IntToString(from = 0,    to = "false/NO_ID")
        })

        private int[] mRules = new int[VERB_COUNT];
        private int[] mInitialRules = new int[VERB_COUNT];

        private int mLeft, mTop, mRight, mBottom;

        private boolean mRulesChanged = false;
        private boolean mIsRtlCompatibilityMode = false;

        /**
         * When true, uses the parent as the anchor if the anchor doesn't exist or if
         * the anchor's visibility is GONE.
         */
        @ViewDebug.ExportedProperty(category = "layout")
        public boolean alignWithParent;