ConstraintLayout初步探究

Posted by alonealice on 2017-12-18

ConstraintLayout是这两年Google新推出的一个布局,俗称约束布局。相比于之前常用的线性布局和相对布局,ConstraintLayout能够使用的场景更多,能更好的见地页面的布局层级,提升页面的渲染性能。

目前稳定版本是1.0.2,本文后面的内容也都是基于该版本。

基本相对位置属性

ConstraintLayout有多个相对位置属性,满足开发者在构建界面的需要,主要使用的如下:

1
2
3
4
5
6
7
8
layout_constraintTop_toTopOf — 期望视图的上边对齐另一个视图的上边。
layout_constraintTop_toBottomOf — 期望视图的上边对齐另一个视图的底边。
layout_constraintBottom_toTopOf — 期望视图的下边对齐另一个视图的上边。
layout_constraintBottom_toBottomOf — 期望视图的底边对齐另一个视图的底边。
layout_constraintLeft_toLeftOf — 期望视图的左边对齐另一个视图的左边。
layout_constraintLeft_toRightOf — 期望视图的左边对齐另一个视图的右边。
layout_constraintRight_toLeftOf — 期望视图的右边对齐另一个视图的左边。
layout_constraintRight_toRightOf — 期望视图的右边对齐另一个视图的右边。

这些属性,从命名上就可以看出它的使用效果,这里就不再详细解释了。不过有一点,这些属性除了可以设置另一个view座位基准,还可以设置其父控件(也就是)ConstraintLayout,比如,将一个view设置在ConstraintLayout中间,就可以这样设置:

1
2
3
4
5
6
7
8
9
<View
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@color/colorPrimaryDark"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent">
</View>

偏移

这设置居中后,可以设置其向某一个方向偏移:

1
2
layout_constraintHorizontal_bias //水平方向
layout_constraintVertical_bias //垂直方向

这两个参数的值都是0-1,当大于1是,view会移出屏幕,小于1时无效。在具体理解上,比如说,当layout_constraintHorizontal_bias=0.25时,相当于在水平方面,从左向右,空余部分宽度的0.25处。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<View
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@color/colorPrimaryDark"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="0.25"
app:layout_constraintLeft_toLeftOf="parent">
</View>

<View
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@color/colorAccent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent">
</View>

效果:

可见属性

visiable是之前就有的可见属性,在ConstraintLayout中作用也是一样的,不过当设置一个View为visiable=GONE时,与它相关的约束条件依旧是存在的。同时,我们还可以使用layout_goneMarginLeft、layout_goneMarginRight、layout_goneMarginTop、layout_goneMarginBottom来设置在约束view不可见的情况下的距离。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<View
android:id="@+id/v1"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@color/colorPrimaryDark"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent">
</View>

<View
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@color/colorAccent"
app:layout_goneMarginLeft="100dp"
app:layout_goneMarginTop="100dp"
app:layout_constraintLeft_toRightOf="@+id/v1"
app:layout_constraintTop_toBottomOf="@+id/v1">

效果图:

宽高比

ConstraintLayout中可以使用layout_constraintDimentionRatio属性来直接设置View的宽高比。

使用方法有如下几种:

1.直接使用float设置:

1
app:layout_constraintDimensionRatio="2"//宽:高=2

2.使用比值设置:

1
app:layout_constraintDimensionRatio="2:1"////宽:高=2

3.自定义宽高比:

1
2
app:layout_constraintDimensionRatio="W,1:2"//宽:高=2
app:layout_constraintDimensionRatio="H,1:2"//宽:高=0.5

链式约束

链这个概念是约束布局新提出的,它提供了在一个维度(水平或者垂直),管理一组控件的方式。使用时,我们需要将整条链上的view都相互约束,同时,处于水平或者垂直方向第一个控件为chain head(链头),当我们给chain head设置layout_constraintHorizontal_chainStyle或layout_constraintVertical_chainStyle,整条链的状态将会发生改变。

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
<View
android:id="@+id/v1"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintHorizontal_chainStyle="spread"
android:background="@color/colorPrimaryDark"
app:layout_constraintRight_toLeftOf="@+id/v2"
app:layout_constraintLeft_toLeftOf="parent">
</View>

<View
android:id="@+id/v2"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#453535"
app:layout_constraintLeft_toRightOf="@id/v1"
app:layout_constraintRight_toLeftOf="@+id/v3">
</View>


<View
android:id="@+id/v3"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@color/colorAccent"
app:layout_constraintLeft_toRightOf="@id/v2"
app:layout_constraintRight_toRightOf="parent"
>
</View>

效果图:

这里layout_constraintHorizontal_chainStyle或layout_constraintVertical_chainStyle有3个参数:

packed:首尾两条链将会分配空间,链内部将不会分配空间

spread:元素之间的空间将会均匀分布,这是系统默认的排列方式

spread_inside:首尾的两条链将不会分配空间,其余内部的链将均匀分配空间。

最后

ConstraintLayout一开始觉得没什么特殊的,用起来还麻烦。但是在实际使用后,发现其确实可以避免很多布局嵌套的问题。本文简略的介绍了它的基本用法,如果需要更好的了解,可以去看官方详细的文档。同时,最新的ConstraintLayout也添加了一些新属性,功能也变得更加强大。