随着移动设备的普及,用户对于应用程序的UI界面要求越来越高。开发人员要在保证应用性能的同时,尽可能的构建复杂而美丽的UI界面成为了必然趋势。而在Android中,ConstraintLayout提供了一种非常有效的方式来构建复杂而美丽的UI界面。
一、ConstraintLayout简介
ConstraintLayout是Android Studio自带的、适用于Android 2.3及更高版本的布局方式,它采用了一种更加灵活的方式来约束各个组件之间的相对位置。
相比于RelativeLayout和LinearLayout等传统布局,ConstraintLayout具有更高的性能和更丰富的功能。它既能够简单地实现线性布局和相对布局,又能够实现复杂的布局比如链表布局、百分比布局等等。而在实现复杂布局的同时,还可以有效地避免布局嵌套和性能问题。
二、ConstraintLayout基本用法
相信大多数开发人员都已经了解了ConstraintLayout的基本用法,例如match_parent、wrap_content等属性的使用。我们在此重点介绍一些较为复杂的用法,例如链表布局和动态布局。
1. 链表布局
链表布局是指多个组件按照一定规则在界面中形成一条链表,在ConstraintLayout中使用的就是HorizontalChain和VerticalChain两个属性。下面我们以HorizontalChain为例来介绍链表布局的使用:
<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">
<Button
android:id="@+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/btn_2"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<Button
android:id="@+id/btn_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2"
app:layout_constraintLeft_toRightOf="@id/btn_1"
app:layout_constraintRight_toLeftOf="@id/btn_3"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<Button
android:id="@+id/btn_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3"
app:layout_constraintLeft_toRightOf="@id/btn_2"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout>
在上面的代码中,我们使用了HorizontalChain属性来实现三个Button组成的链表布局。其中,HorizontalChainStyle属性采用了spread_inside的方式来对三个Button进行布局。整个布局如下图所示:
![Chain Layout 1](https://img-blog.csdn.net/20180906094513116?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3l1Y2hpbmV5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/q/70 "Chain Layout 1")上图演示了三个Button之间对齐方式为水平方向,且第一个和第二个Button的右侧及左侧分别连接、中间的两个Button的左右两侧彼此连接,最后一个Button与父容器右边缘连接的布局效果。
需要注意的是,HorizontalChainStyle属性的取值包括spread_inside、spread、packed三种方式,在不同的布局需求下可以灵活运用。
2. 动态布局
动态布局使用ConstraintSet来实现,可以在代码中动态的修改ConstraintLayout中各个组件之间的布局关系。下面举个例子说明:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/layout_root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<Button
android:id="@+id/btn_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2"
app:layout_constraintLeft_toRightOf="@id/btn_1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<Button
android:id="@+id/btn_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3"
app:layout_constraintLeft_toRightOf="@id/btn_2"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout>
在上面的代码中,我们定义了三个Button组成的链表布局,但存在一个问题,就是三个Button之间的宽度并不相等。我们可以通过如下代码对ConstraintLayout中的各个组件的宽度进行动态设置:
ConstraintLayout layout = findViewById(R.id.layout_root);
ConstraintSet set = new ConstraintSet();
set.clone(layout);
set.constrainWidth(R.id.btn_1, 0);
set.constrainWidth(R.id.btn_2, ConstraintSet.MATCH_CONSTRAINT);
set.constrainWidth(R.id.btn_3, 0);
set.applyTo(layout);
在上述代码中,首先通过findViewById方法获取到了ConstraintLayout对象,然后通过ConstraintSet对其进行备份。接下来,我们调用了set.constrainWidth方法对各个Button的宽度进行设置。在这里,我们设置第一个和最后一个Button的宽度为0,中间的Button的宽度设置为MATCH_CONSTRAINT,这样就保证了三个Button的宽度都相等了。最后,我们再次调用set.applyTo方法将设置应用到具体的UI界面中。
三、ConstraintLayout最佳实践
虽然ConstraintLayout有着非常多的功能和使用技巧,但是,在使用时还需要注意一些最佳实践。下面我们总结了几个常见的实践建议:
1. 避免随意嵌套
和其他ViewGroup一样,ConstraintLayout中的嵌套层数也会影响应用程序的性能。因此,在使用ConstraintLayout时,应尽量避免无意义的嵌套。使用include控件来引用其他布局是一种很好的解决方案,同时也能够使布局更加复用。
2. 使用Guideline调整间距
Guideline是Android ConstraintLayout中一个非常有用的工具,它可以用来调整视图之间的间距和位置。其实现方式是在布局中添加一条垂直或者水平的虚线来占据特定位置,并将组件对该虚线进行约束。在实际应用中,可以使用Guideline调整一个界面元素的位置和大小。
3. 适当使用Barrier
Barrier是Android ConstraintLayout中的一个不太常用,但是非常有用的控件,它类似于在布局中添加一条虚拟的屏障。它能够实现当一个组件的一些边缘需要作为约束的时候,自动生成一个虚拟的屏障。在实际应用中,适当使用Barrier能够使布局更加简单和容易维护。
四、总结
本文主要介绍了Android ConstraintLayout的基础用法和高级用法,同时也介绍了常见的最佳实践。当然,这只是冰山一角,除此之外还有很多其他的相关技术,如果开发人员能够充分发挥其所长,非常简单就可以实现复杂而美丽的UI界面。