使用ConstraintLayout构建一个灵活的布局

简介

ConstraintLayout允许你在不使用任何嵌套的情况下创建大型而又复杂的布局。它与RelativeLayout非常相似,所有的view都依赖于兄弟控件和父控件的相对关系。但是,ConstraintLayout比RelativeLayout更加灵活且在Android Studio的布局编辑器中更易于使用。
由于ConstraintLayout所能做的一切都可以从布局编辑器的可视化工具中直接获取,所以你可以完全使用拖拽的方式来构建布局。此外,ConstraintLayout可以兼容到Android 2.3 (API9),所以我们不用担心兼容上的问题。

概要

想要在ConstraintLayout中定义一个View的位置,你至少需要添加两个约束:一个水平方向,一个竖直方向。当然,你可以添加更多的约束。
如果你没有指定某个方向上的约束,那么该View将会在坐标(0,0)或(x,0)或(0,y)处显示(这取决于你没有指定哪个方向的约束)。
如下图,TextViewC没有指定垂直方向的约束,虽然在预览时你看到的效果没有问题,但是运行后会发现,该View的显示坐标为(x,0)。
image_1at3qdkjc1cuv1cdd15kkvlr9tqm.png-126.8kB

所以在使用约束时务必要检查下布局文件有没有提示约束问题。

如何使用ConstraintLayout

首先去SDK Tools中勾选Show Package Details安装相应的ConstraintLayout版本(ConstraintLayout for AndroidSolver for ConstraintLayout)。
image_1at84l0i316io9ssvsf148hpaum.png-89.3kB
然后在模块的build.gradle中如下引用即可(记得改为你安装的版本号)。

1
2
3
dependencies {
compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8'
}

使用ConstraintLayout有两种方式,一种是直接创建一个新布局,然后将根节点修改为android.support.constraint.ConstraintLayout。另一种是将原来的布局右键转换为ConstraintLayout.
image_1at84t7re14b618kg1ki7bc11dad9.png-21.9kB

添加约束

Parent constraint

所谓父约束,即连接View的某一边到父布局的边缘。如下图,指定该View距父布局的左边缘为128dp
1.gif-242.4kB

Position constraint

位置约束,该约束主要用于控制两个View的相对位置,即控制两个View在水平和竖直方向展示的先后顺序。如下图,Button被约束于ImageView的下方64dp处。
1.gif-311.7kB

Alignment constraint

对齐约束,用于对齐两个View的相同边缘。如下图,我们将ImageView和Button的左边缘进行对齐。
1.gif-321.4kB
当然,我们还可以做一下偏移对准,如下为,Button相对于ImageView 40dp的偏移对齐。这40dp的约束是通过Margin来实现的。
1.gif-53.7kB

Baseline alignment constraint

基准线对齐,该对齐方式主要用于文字之间。使用该约束,我们可以将两个View中的文字做基准线对齐操作。
1.gif-251.5kB

Constrain to a guideline

引导线约束,我们可以添加一个水平或者竖直的引导线来粘附约束。开发者可以放心。你的guideline是不会被用户看见的。
image_1at8b2o181gjf1muotr516tm1fam2i.png-37.9kB
点击guideline边缘的圆圈,用于切换guideline位置的测量模式(百分比/dp)。
1.gif-513.5kB

使用自动连接和推断约束

我们还可以使用自动连接(Autoconnect)和推断约束(Infer Constraints)功能,使用之前,先了解下这两者的区别。
推断约束,我们只需要点击一下推断约束按钮,它将会扫面整个布局以确定最有效的的约束关系,然后自动创建元素之间的约束。
自动连接,仅仅为你刚加入的View创建一个约束(后期拖动不会改变约束),它仅仅根据最近的元素来创建约束。
image_1at8e09921psd13p15uqnn91db843.png-11.1kB
演示如下:
1.gif-473.9kB

调整View的尺寸

通过布局编辑器的右边栏,我们可以通过调节View的相关尺寸。
image_1at8eouph1hfi1aqb1gv98todh05m.png-19.5kB
View尺寸有三种,固定尺寸,WrapContent,AnySize。对应图如下(固定尺寸就是上图中的直线段)。
image_1at8fg5gsga11por01hvi1bk863.png-5.7kB
其中AnySize类似于LinearLayout中尺寸为0dp,layout_weight1的情况。会将尺寸扩展到当前约束下的所有空间。

调节约束偏向,则在于如果一个View的两端指定了约束,我们可以调节约束偏向来控制位置权重。
演示图如下:(下图View中左边缘和右边缘都指定了约束)
1.gif-1153.2kB

此外,我们可以给每个View指定默认Margin。当然,可以单独在Properties右边栏中进行调整。
image_1at8gttga639a5j1mr4pntq16s.png-13.4kB

ps: 需要注意的是在ConstraintLayout中不要使用match_parent而应使用AnySize0dp,

最后

参考资料:Build a Responsive UI with ConstraintLayout