ConstraintLayout基础

ConstriantLayout

是什么?

ConstraintLayout,中文称约束布局,在2016年Google I/O大会时提出,2017年2月发布正式版,目前稳定版本为1.0.2。约束布局作为Google今后主推的布局样式,可以完全替代其他布局,降低页面布局层级,提升页面渲染性能。

使用

ConstraintLayout支持最低Android Studio版本是2.2,但是有些属性在2.2的布局编辑器上不支持编辑,如比例和baseline等约束。所以推荐使用2.3的版本,当然3.0的版本那就更好了。要使用ConstraintLayout,需要在项目中进行如下配置:
升级新版本的Android Studio 会默认添加这些依赖

Maven 依赖

implementation 'com.android.support.constraint:constraint-layout:1.1.2'

特性

  • 高级版RelativeLayout
  • 极大减少布局的嵌套,提高xml加载速度
  • 编写方式相对自由,可以实现各种复杂的样式

缺点

  • 大量增加xml行数
  • 需要定义大量的id

位置约束

位置约束属性有上下左右四个方向,上下两个方向各2个,左右两个方向各4个,在加上1个基线共计13个约束属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
layout_constraintLeft_toLeftOf
layout_constraintLeft_toRightOf
layout_constraintRight_toLeftOf
layout_constraintRight_toRightOf
layout_constraintTop_toTopOf
layout_constraintTop_toBottomOf
layout_constraintBottom_toTopOf
layout_constraintBottom_toBottomOf
layout_constraintStart_toEndOf
layout_constraintStart_toStartOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf
layout_constraintBaseline_toBaselineOf

属性名已经非常直观了,基本就是:layout_constraint[自己的位置]_[目标的位置]="[目标ID]"
如果是相对父布局的话,不需要id直接写parent就好

Margin

ConstriantLayout中除了通常版本的Margin以外,还有一个叫goneMargin的东西,这个属性的意思是当用来约束的View处于gone的时候,被约束View的Margin:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/sample1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="A"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="10dp"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="B"
app:layout_goneMarginStart="10dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/sample1"
android:layout_marginStart="20dp"/>

</android.support.constraint.ConstraintLayout>

Margin.1

当我们把Bvisibility设置为gone之后

Margin.2

此时Bmargin就是layout_goneMarginStart的值了

比例分布

当为一个View在同一方向上添加2个约束的时候,该View就会处于两个边界中间的位置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/sample1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="A"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Alt text

如果我们不想让这个View位于正中间,则可以使用一下两个属性:

1
2
layout_constraintHorizontal_bias
layout_constraintVertical_bias

分别是水平和垂直方向上所占的比例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/sample1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="A"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Alt text

圆形约束

除了上下左右4个方向的约束之外,还可以某个View为圆心做圆形约束:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/sample1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="A"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="A"
app:layout_constraintCircle="@id/sample1"
app:layout_constraintCircleRadius="50dp"
app:layout_constraintCircleAngle="45"/>

</android.support.constraint.ConstraintLayout>

Alt text

尺寸约束

android:layout_widthandroid:layout_height可以设置3种类型的值:

  • 具体的数值,比如200dp
  • wrap_contentView有多大显示多大
  • 0dp,根据约束充满可用空间

需要注意的是,如果View设置为wrap_content的话,其大小是不受约束控制的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/sample1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:paddingStart="20dp"
app:layout_constrainedWidth="false"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
app:layout_constraintEnd_toStartOf="@+id/sample2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/sample2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:lines="1"
android:text="B"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

</android.support.constraint.ConstraintLayout>

Alt text

如果在wrap_content的同时也需要受到约束控制,则可以使用以下两个属性

1
2
app:layout_constrainedWidth
app:layout_constrainedHeight

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/sample1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:paddingStart="20dp"
app:layout_constrainedWidth="true"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
app:layout_constraintEnd_toStartOf="@+id/sample2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/sample2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:lines="1"
android:text="B"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

</android.support.constraint.ConstraintLayout>

Alt text

百分比尺寸

当宽或者高的某一项设置为0dp时,可以用app:layout_constraintWidth_defaultapp:layout_constraintWidth_percent两个属性来设置View将占据剩余空间的百分比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/sample1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="A"
app:layout_constrainedWidth="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/sample2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:lines="1"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="B"
android:gravity="center"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/sample1"
app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Alt text

Ratio

可以根据控件的宽或者高,让一个属性与另一个属性成特定的比例。被设置为0dp的一方会根据另一方的值,以layout_constraintDimensionRatio属性指定的比例进行设置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/sample1"
android:layout_width="0dp"
android:layout_height="50dp"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:text="A"
app:layout_constraintDimensionRatio="2:1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Alt text

其中layout_constraintDimensionRatio可以设置为:

  • 浮点值,表示宽高比
  • 宽 : 高的形式

如果宽和高都设置成0dp也是可以使用比例的,为了约束其中一条边,需要在比例前面添加W或者H表示被约束的是哪一条边:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/sample1"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:text="A"
app:layout_constraintDimensionRatio="H, 2:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Alt text

Chains

类似于LinearLayout中的weight。如果控件之间的添加了双向约束,则这两个控件就会形成一个链。并且可以在链头,也就是水平最左端,垂直最顶端的控件上设置链的样式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/sample1_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="A"
app:layout_constraintEnd_toStartOf="@+id/sample1_2"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/sample1_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="B"
app:layout_constraintEnd_toStartOf="@+id/sample1_3"
app:layout_constraintStart_toEndOf="@id/sample1_1"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/sample1_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="C"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/sample1_2"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/sample2_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="A"
app:layout_constraintEnd_toStartOf="@+id/sample2_2"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/sample1_1" />

<TextView
android:id="@+id/sample2_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="B"
app:layout_constraintEnd_toStartOf="@+id/sample2_3"
app:layout_constraintStart_toEndOf="@id/sample2_1"
app:layout_constraintTop_toBottomOf="@id/sample1_1" />

<TextView
android:id="@+id/sample2_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="C"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/sample2_2"
app:layout_constraintTop_toBottomOf="@id/sample1_1" />

<TextView
android:id="@+id/sample3_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="A"
app:layout_constraintEnd_toStartOf="@+id/sample3_2"
app:layout_constraintHorizontal_bias="0.3"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/sample2_1" />

<TextView
android:id="@+id/sample3_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="B"
app:layout_constraintEnd_toStartOf="@+id/sample3_3"
app:layout_constraintStart_toEndOf="@id/sample3_1"
app:layout_constraintTop_toBottomOf="@id/sample2_1" />

<TextView
android:id="@+id/sample3_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="C"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/sample3_2"
app:layout_constraintTop_toBottomOf="@id/sample2_1" />

<TextView
android:id="@+id/sample4_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="A"
app:layout_constraintEnd_toStartOf="@+id/sample4_2"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/sample3_1" />

<TextView
android:id="@+id/sample4_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="B"
app:layout_constraintEnd_toStartOf="@+id/sample4_3"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintStart_toEndOf="@id/sample4_1"
app:layout_constraintTop_toBottomOf="@id/sample3_1" />

<TextView
android:id="@+id/sample4_3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="C"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="3"
app:layout_constraintStart_toEndOf="@id/sample4_2"
app:layout_constraintTop_toBottomOf="@id/sample3_1" />

</android.support.constraint.ConstraintLayout>

Alt text

Barrier

Barrier是一个不可见的辅助控件,它用于阻止一个或多个控件越过自己,它的位置是由最长或者最高的控件决定的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/sample1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="A"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/sample2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="BBBBBBBBBBBBBBBB"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/sample1" />

<android.support.constraint.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="sample1, sample2" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="C"
app:layout_constraintStart_toEndOf="@id/barrier"
app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Alt text

Group

Group也是一个不可见的辅助控件,它可以对一组控件进行设置,避免一个一个设置的蛋疼情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/sample1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="A"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/sample2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="B"
app:layout_constraintStart_toEndOf="@id/sample1"
app:layout_constraintTop_toTopOf="parent" />

<android.support.constraint.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="sample1, sample2" />

</android.support.constraint.ConstraintLayout>

Alt text

如果将Group的visibility设置为gone,则这两个TextView都会消失。

需要注意的是,一个控件只能加入1个Group,如果加入了多个Group那么只有最后一个Group可以控制该控件,另外加入了Group的控件的visibility属性只能由Group,哪怕该控件自己也无法控制。

Guideline

也是一个不可见的辅助控件,用来添加水平或者垂直的辅助线,其位置可以用以下3种形式设置

  • layout_constraintGuide_begin:指定距离布局左侧或顶部的固定距离
  • layout_constraintGuide_end:指定距离布局右侧或底部的固定距离
  • layout_constraintGuide_percent指定位于布局的宽或者高的百分比
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.constraint.Guideline
android:id="@+id/guideline1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="50dp" />

<TextView
android:id="@+id/sample1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="A"
app:layout_constraintStart_toEndOf="@id/guideline1"
app:layout_constraintTop_toTopOf="parent" />

<android.support.constraint.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_end="50dp" />

<TextView
android:id="@+id/sample2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="B"
app:layout_constraintBottom_toTopOf="@id/guideline2"
app:layout_constraintStart_toStartOf="parent" />

<android.support.constraint.Guideline
android:id="@+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />

<TextView
android:id="@+id/sample3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_gray_line_white_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:text="C"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/guideline3"
app:layout_constraintStart_toStartOf="@id/guideline3"
app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>