layout布局_关于 layout_weight,你到底知多少
- 什么是 layout_weight
layout_weight 是 Android 线性布局中的权重表示方式, 用来表示子布局所占父布局的比重。
若 C-child 表示子布局声明的大小,B-blank 表示剩余布局的大小,P-percent 表示子布局占据父布局剩余布局的比例,则子布局最终的实际大小 R-reality 为:
R = C + B * P
通过以上公式,下面的布局依然成立: left 所占宽度:R = 0 + B * (1/2) = (1/2) * B
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal"><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:background="@color/orange_ff9800"android:padding="6dp"android:text="left"android:textColor="@color/white"/><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:background="@color/blue_31b6e7"android:padding="6dp"android:text="right"android:textColor="@color/white"/></LinearLayout>

- weightSum
LinearLayout 有个权重数量的标记:weightSum
,以上布局中两个 TextView 分别声明了自己的权重,在 LinearLayout 没有声明 weightSum
时,默认的权重数量就是子布局权重之和:2。
如果将以上布局的 Linearlayou 权重之和声明为 4:
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:weightSum="4"android:background="@color/gray_e0e0e0"><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:background="@color/orange_ff9800"android:padding="6dp"android:text="left"android:textColor="@color/white"/><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:background="@color/blue_31b6e7"android:padding="6dp"android:text="right"android:textColor="@color/white"/></LinearLayout>
则子布局的显示如下:

- 0dp 与 wrap_content
谷歌官方建议子布局的 layout_width 使用 0dp,来分比例显示布局,和 wrap_content 大同小异,当使用 layout_weight 时,都表示占据剩余宽度或高度的比重。
但两者有明显区别。
使用 0dp 时,要考虑所分配的布局宽度是否小于控件实际宽度,比如:
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:background="@color/gray_e0e0e0"><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:background="@color/orange_ff9800"android:padding="6dp"android:text="left"android:textColor="@color/white"/><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="19"android:background="@color/blue_31b6e7"android:padding="6dp"android:text="right"android:textColor="@color/white"/></LinearLayout>

而使用 wrap_content 不必考虑这样的问题:
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:background="@color/gray_e0e0e0"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:background="@color/orange_ff9800"android:padding="6dp"android:text="left"android:textColor="@color/white"/><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="19"android:background="@color/blue_31b6e7"android:padding="6dp"android:text="right"android:textColor="@color/white"/></LinearLayout>

- wrap_content 与 match_parent
当子布局的高宽声明为 match_parent 时,所显示的效果与 wrap_content 截然相反。
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:background="@color/gray_e0e0e0"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:background="@color/orange_ff9800"android:padding="6dp"android:text="left"android:textColor="@color/white"/><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="2"android:background="@color/blue_31b6e7"android:padding="6dp"android:text="right"android:textColor="@color/white"/></LinearLayout>

究其原因,都是 match_parent 在捣鬼。
来看下文章开始时的公式: R = C + B * P
以 left 控件为例,此时的 B(剩余布局) = 父布局大小 - 子控件大小之和,父布局大小也就是 C(因为声明的是 match_parent),而子控件大小之和是 2C,所以 :
B = C - 2C = -C
, R = C + B * P = C + (-C) * (1/3) = (2/3) * C
其实,以上公式恒成立,关键在于,当子控件的高宽声明为 match_parent 时的剩余布局大小要搞清楚。剩余布局大小 = 父布局大小 - 子布局大小之和
