最近把 AS 升级了一下,发现新建项目 Activity 默认使用了 ConstraintLayout 这个布局,于是赶紧搜索了一下,发现这个ConstraintLayout 与其说是一个布局,不如说是一种新的可视化编辑布局文件方式。AS 此前并不实用的可视化布局编辑方式,在有了 ConstraintLayout 后,可以成为一种新的选择。虽然在实际应用场景下还存在不少掣肘,但是除了可视化的编写方式可以大大提升的开发速度之外,对某些传统写法需要多层嵌套才能实现的布局也不失为另外一种解决方式。
基本使用
创建布局
在 AS2.3 以上版本只需直接新建项目,选择 EmptyActivity 即可,AS 会默认使用 ConstraintLayout 作为布局。低版本下,需要添加依赖:
compile 'com.android.support.constraint:constraint-layout:1.0.2'
并且在xml文件的可视化编辑页面,在布局上右键,转化为 ConstraintLayout 。
成功创建布局后在左上角选择相应控件拉到布局中即可。
基本操作
当我们把控件拉布局中,控件会变成下图这样的状态:
我们可以看到四边上分别有一个空心的圆点,四个角分别有一个方点,控件下紧贴着两个可操作的按钮。
边上这四个圆点是最重要的,用于添加约束。按着它不放,可以拉出一个带箭头的线,这条线叫做约束(Constraint),当箭头碰到父布局的边或者其他控件四边上的空心圆时就会吸附上去,同时可以马上看到控件向箭头指定的边对齐。
四角上的方点用于改变控件大小。
控件下有 ab 字样的按钮用于添加文字基准线约束,只有带文字的控件才会出现这个按钮,且该约束也只能指向另一个带文字控件的文字基准线。
最后一个带有叉叉的按钮用于删除该控件的所有约束。
另外删除约束还有两种方式:
点击已经添加约束的圆点,可以删除单个约束。上方工具栏的
clear all constraint
按钮则可以删除整个页面所有约束。
约束解析
我们现在添加一个 Button 到布局里,只为其添加水平上指向父布局右边的约束,然后运行。
可以看到结果虽然水平方向是向屏幕右边对齐了,但是垂直方向却和预览不同。ConstraintLayout 的可视化编辑并没有看起来那么神奇,实际上只是 AS 为我们自动写入 xml 代码而已,看一下 AS 生成的代码会发现 ConstraintLayout 其实和 RelativeLayout 非常相似,主要也是靠其他控件或者父布局的相对位置来实现定位。
像上面那个例子,我们只指定了水平方向上的约束,垂直方向 AS 上并没有生成相应代码,所以控件的垂直位置会默认对齐父布局的上边(相应的水平方向会对齐左边)。打开其 xml 代码,我们可以看见,刚才添加的约束,实际上生成了这样一句代码:
app:layout_constraintRight_toRightOf="parent"
可以看出其实约束的具体代码格式是这样:app:layout_constraintXxx_toXxxOf="xxxxx"
。
这个 ConstraintLayout 独有的属性,可以先简单理解为控件的某一边向目标控件的某一边对齐。和RelativeLayout 的 layout_alignXxx 相对控件对齐属性比较接近,而且toXxxOf
多了目标控件的方向的指定,所以更加强大,还可以实现 RelativeLayout 的相对控件并列、相对父布局居中等效果,甚至可以实现 RelativeLayout 做不到的控件居中排列。
在水平或垂直方向上指定一个方向的约束可以理解为向某边对齐,同方向上同时指定反向两个约束则可以理解为在两边之间居中。如下图:
上图将控件的四边约束指向父布局的四边,使得控件在父布局的水平和垂直方向上居中,从而实现相对整个父布局居中的效果。
相对控件居中也是一样的方法。
Guideline
约束除了可以指向父布局和其他控件的四边之外,还可以指向Guideline。Guideline是一个不显示的View,类似于布局的参考线,通过Guideline可以实现让控件的约束指向父布局高度的 50%、25%之类比较常见的需求。
点击预览上方的 Guideline 按钮,然后选择 Guideline 的方向,Guideline就会自动添加到布局中。Guideline显示的参考数值有 3 个模式,默认是距离父布局上或左边的距离,还有相对另一边距离,在方向上的百分比。通过点击其左或上端的圆形按钮,可以循环切换三种模式。
bias和margin
除了对齐和居中,其他精细的定位主要通过 bias 和 margin 来实现。
指定margin主要有两种方式,第一种是添加对齐约束后(不能是居中约束)直接拉动控件到合适距离,第二种是在右边的 properties 栏中直接指定。
需要注意的是在 ConstraintLayout 中 margin 不是指该控件和其他控件或者父布局某边的距离,而是指该控件与指定了约束的某条线的距离。所以控件间相对某边对齐,需要注意把某边的margin调整为0。
另外设置了居中约束的控件,可以通过拉动properties 栏四边上的滑块,或者直接拉动控件来调整 bias。
bias 可以理解为控件在反向两个约束的偏移距离,默认值是 0.5,调整到 0 或 1 时会完全对齐其中一边。
chain
ConstraintLayout 还提供了一个叫做 chain
的属性。该属性可以在同一个轴上(水平或者垂直)为多个控件提供一个类似群组的统一表现。另一个轴可以单独控制。
选中多个控件后,点击工具栏上的 Center Vertically,或者Center Horizontally 按钮,可以看到控件间出现了锁链状的连线和一个锁链按钮。点击锁链按钮,可以切换控件组在指定的轴上的分布形式。
控件尺寸
控件尺寸除了可以拉动控件四角改变之外,还可以在 properties 栏上编辑。
可以看到在最中间的那个正方形区域可以改变控件的宽高的模式:
另外 match parent 虽然在 ConstraintLayout 中依然有效,但是 ConstraintLayout 的一大特色就是减少嵌套,所以不太用到,与之类似的就是 any size 属性。any size和 match parent 的区别在于,match parent是用于填充满当前控件的父布局,而any size是用于填充满当前控件的约束规则。所以约束规则改变时,控件的大小也会改变。
上面的例子中,上方的 Button 约束指向父布局上边和另一个 Button,当另一个 Button 发生变化时,上方 Button的约束也发生了变化,同时高度也随之变化。
可视化编辑界面简介
可视化编写布局比较容易上手,基本上了解一下整个界面,自己试一试就明白了,所以这里对整个界面进行一点介绍。
ConstraintLayout 的可视化编辑界面主要分为五个部分:
- 1 Palette 用于选择控件,左边列是控件的分类,右列是控件列表,下面是控件的预览。
- 2 Component Tree,显示当前布局包含所有控件。
- 3 工具栏,其中有对齐控件、智能添加约束等用于快速编辑布局的功能按钮。
- 4 编辑窗口。
- 5 Properties,用于设定选中控件的各种属性。注意上方有一个放大镜按钮,可以用来搜索控件属性。
特别提一下,工具栏上有一个Infer Constraints (智能添加约束)按钮,这个功能比较好用。
只需要在编辑窗口把控件摆好,然后点一下 Infer Constraints 按钮,就可以看到所有控件的约束都已经自动添加好了。
引入自定义View
在上图的例子里我提前添加了比较常用的 RecyclerView 的依赖,然后在 Component Tree 中选中 Advanced
分类,把 view 拖拽到编辑窗口中,会出现项目可用的所有View。直接选中所需 View,或者直接输入 view 的名称进行搜索也可以。
总结
ConstraintLayout 在上手之后速度明显要比传统的布局编写方式快上不少,减少嵌套效果明显。虽然现在还存在一些问题,维护起来也感觉比较麻烦,在项目中作为主要方式使用可能还不太现实。但是平时写写 Demo 用起来还是不错的,针对部分布局用来减少嵌套也是个不错的选择。
不管如何,其作为 Google 在去年的I/O大会上强推一个功能,现在更是作为 AS 的默认布局,还是有先了解熟悉一下的必要。
本文主要参考文章:
https://developer.android.com/reference/android/support/constraint/ConstraintLayout.html
http://blog.csdn.net/guolin_blog/article/details/53122387
http://www.jianshu.com/p/beb9f7157209