Android里的ConstraintLayout是个非常强大的工具,它有效的解决了Android里Layout的层级嵌套的问题。使用一个ConstraintLayout可以实现之前多个Layout才能实现的效果。
本篇文章就介绍下ConstraintLayout里比较进阶用法之一:Chain。
Chain简介
顾名思义,Chain就是把几个控件像链条一样连接起来,实现一系列的效果。这个概念看上去有些深奥,其实并不复杂。熟悉js/css等技术的同学会发现这些概念很熟悉。就拿Android来说,使用Chain可以很大程度上在ConstraintLayout里替代原有的LinearLayout和RelativeLayout。
Chain实例
假设我们在UI上有三个控件,横着排成一排。要想应用Chain的效果,需要把这3个控件用“链子连接起来”。
Chain其实并没有定义新的控件,只是使用原来的依赖方式。代码如下:
<Button
android:id="@+id/btn_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是控件A"
app:layout_constraintEnd_toStartOf="@+id/btn_b"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是控件B"
app:layout_constraintEnd_toStartOf="@+id/btn_c"
app:layout_constraintStart_toEndOf="@+id/btn_a"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_c"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是控件C"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/btn_b"
app:layout_constraintTop_toTopOf="parent" />
对照代码,我们来看看具体的链接是如何实现的:
- 控件A,左端依赖父容器,右端依赖控件B。
- 控件B,左端依赖控件A,右端依赖控件C。
- 控件C,左端依赖控件B,右端依赖父容器。
通过3个控件的两两互相依赖,我们实现了把他们链接起来的目的,接下来就可以应用Chain的各种效果了。应用的方式也很简单,就是在链头(所谓链头,就是水平链中最左侧的控件以及垂直链中最顶部的控件),也就是控件A上加上一句:app:layout_constraintHorizontal_chainStyle="XXX"
,其中XXX就是想要的效果,可能的取值有:Spread、Spread inside、Packed
几种。
<Button
android:id="@+id/btn_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是控件A"
app:layout_constraintEnd_toStartOf="@+id/btn_b"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
接下来我们来看看各种取值具体的效果:
spread:
这种效果很简单,就是3个控件把整个横向空间平分。
spread_inside:
这种效果也是非常常见的,两端两个控件靠边对齐,中间的控件平分剩下的空间。
weighted:
在使用spread
或spread_inside
模式的时候,可以通过layout_constraintHorizontal_weight
和layout_constraintVertical_weight
来设置某个控件的权重值。这和LinearLayout
里的layout_weight
很相似。不过此时需要把控件的layout_width(水平排列)
或layout_height(垂直排列)
设置为0dp。
比如我们修改下这个例子里的控件B:
<Button
android:id="@+id/btn_b"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="这是控件B"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintEnd_toStartOf="@+id/btn_c"
app:layout_constraintStart_toEndOf="@+id/btn_a"
app:layout_constraintTop_toTopOf="parent" />
此时的效果是这样的:
此时,控件B占满了剩余的空间。
packed:
packed就是把控件都挤在中间显示。这时候,可以通过修改控件A的
layout_marginLeft
值来控制3个控件的整体位置。比如:
<Button
android:id="@+id/btn_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是控件A"
android:layout_marginLeft="100dp"
app:layout_constraintEnd_toStartOf="@+id/btn_b"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
此时3个控件整体向右移动了100dp:
其他
关于Chain还有几个小知识点:
一个控件既可以放在水平链里也可以放在垂直链里,因此可以轻松构建灵活的网格布局。
虽然链的方向为垂直或水平,但使用其中一个方向不会沿该方向与控件对齐。因此,我们必须使用其他约束条件,以保证控件在另外的方向上对齐。比如上面的例子,我们需要
app:layout_constraintTop_toTopOf="parent"
来指定垂直方向的约束。
以上就是ConstraintLayout里Chain基本用法,希望对您有所帮助。