1. 什么是 Chains 链
Chains
是一种特定类型的约束,它允许我们在链内的视图之间共享空间,并控制可用空间在它们之间的划分方式。与传统 Android 布局最相似的应该是 LinearLayout
中的权重比 weight
属性,但 Chains
能做到的要远远比 weight
多。
2. Chain 链模式
前面已经提到了 Chain 链是由多个 View 组成的,所以要创建一个 Chain 链就需要先选择多个想要链接到一起的 Views,然后再通过水平链或垂直链将其链到一起。Chain 链模式一共有三种,分别为:spread
,spread_inside
和 packed
,若想这些模式生效,在链头设置属性即可。
2.1 Spread 模式
模式 | 说明 |
---|---|
spread | Chain 链的默认模式就是 spread 模式,它将平分间隙让多个 Views 布局到剩余空间。 |
图例 | |
![]() |
1 |
|
2.2 Spread Inside 模式
模式 | 说明 |
---|---|
spread_inside | Chain 链的另一个模式就是 spread inside 模式,它会把最边缘的两个 View 到外向父组件边缘的距离去除,然后让剩余的 Views 在剩余的空间内平分间隙布局。 |
图例 | |
![]() |
1 |
|
2.3 Packed 模式
模式 | 说明 |
---|---|
packed | 最后一种模式是 packed ,它将所有 Views 打包到一起不分配多余的间隙(当然不包括通过 margin 设置多个 Views 之间的间隙),然后将整个组件组在可用的剩余位置居中。 |
图例 | |
![]() |
|
在 packed 模式下,可以通过修改偏移值 bias 来进一步控制填充视图的位置。本例中,偏移设置为 0.5,这将使视图居中。 |
1 |
|
3. Spread Chain 的权重
spread
和 spread inside
链可以为链内的每个成员设置 weight
权重,这与 LinearLayout
的 weight
权重设置非常相似。
要将 weight
应用于特定控件,需要将该控件(如果控件在一个水平链中)的宽度属性设置为 0dp,权重属性设置为 1,代码如下:
1 | <TextView |
约束布局官网下的文章 Chains 中描述说 weight
权重在 packed
模式下是无效的,设置了该属性的控件的宽度会收缩到零。但经过实测,最终验证这种说法是不准确的,或许这个属性在最开始的表现正如文章中描述的那样,但不排除后续版本的优化将这种效果去除了。
4. XML 中的 Chain
在 XML 中设置 Chain 其实是 View 间设置双向互补约束的过程。例如,链内的 A 和 B,A 的尾在 B 的首,B 的首在 A 的尾。这种属性的设置,本质上是在相反方向的同一对锚点之间创建了两个约束。这就是 Chain 的定义方式。
另外,还可以通过 spread
,spread_inside
和 packed
来切换链模式,而且这个约束属性必须在链头,即链中的第一个组件。我们可以通过设置 app:layout_contraintHorizontal_bias="0.75"
(值在 0.0 和 1.0 之间)来设置链上的偏移。
最后,我们还可以通过设置属性 android:layout_width="0dp"
以及 app:layout_constraintHorizontal_weight="1"
来设置 Chain 中组件的权重。