ConstraintLayout是什么?你可以理解为一个增强版的RelativeLayout。相比RelativeLayout,ConstraintLayout显得更加灵活,它让布局编辑器变得不再鸡肋。当你拖拽一个控件到ConstraintLayout之后,你可以通过拖拽锚点添加约束。何为约束,简单的说就是页面控件之间的关系。

使用前提
ConstraintLayout必须在Android2.3及以上版本中引入constraint-layout包才可以使用,同时对Android Studio的版本要求必须是2.2及以上。在撰写本篇文章时候,最新的包版本为1.0.0-alpha9
compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha9'
小提示,如果constraint-layout产生升级,它会以警告的方式在xml中提示,这边还需要你自行去更新下载,下载的位置如图所示

约束的定义
约束就是一个控件在屏幕上相对其他控件位置的一种描述,你可以通过下面的方式定义一个单边或多边的约束:
- 和父布局的侧边建立联系: 例如建立一个控件的顶部与ConstraintLayout顶部的联系。
- 和其他控件的侧边建立联系: 例如控件A的顶部与控件B的底部建立联系,那么控件A就会出现在控件B的下方。
- 和其他控件的基准线对齐: 例如将TextViewA的基准线与TextViewB的基准线对齐。相比边界对齐,该约束对于文字控件来说显得更重要。
至于如何生成约束,下面会具体提及
如何使用ConstraintLayout
将传统xml布局文件转换成ConstaintLayout非常简单,只要在Design视图下选择Component Tree面板,找到你的布局文件,右键将其一键转换即可


再看看xml
<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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="16dp" />
</android.support.constraint.ConstraintLayout>
我们发现布局模板变的跟之前不一样了,多了一些箭头、圆点之类的,而且xml中的rootView也变成ConstraintLayout了。别慌,我们一个个的来进行解释
功能图标说明
-
Hide Constraints
显示或隐藏约束条件,默认是不显示的,只有点击控件才能出现约束连接线
Hide Constraints
-
Autoconnect
自动生成约束的功能默认是开启的,这个特性可以为你拖进布局中的控件自动添加一个或多个约束。注意,它仅为当前正在移动的控件创建约束。如果你不需要这个功能,可以单击进行关闭。
Turn On Autoconnect
-
Infer Constraints
自动推断约束,推断并且自动添加它认为的约束条件。这里与Autoconnect的区别在于推断约束会创建布局上所有元素之间的约束
Infer Constraints
-
Clear All Constaints
清除所有约束关系
Clear All Constaints
拖拽功能说明
-
约束手柄的类型
三种拖拽区域
如图,以TextView所示,
圆点(锚点)为侧边约束手柄,可以建立控件之间边的关联关系,
正方形为尺寸手柄,可以调整控件大小,
中间的椭圆形为基准线约束手柄:,可以进行控件基准线约束的操作 -
生成约束规则
当你创建一个约束的时候,一定要记得下面几点规则:
(1) 每个控件最好有两个约束:一个水平方向的一个垂直方向的,否则xml就会有警告提示,并且布局编辑器编辑器右上角也会有相应的提示
没有添加完整约束的数量
没有添加约束
只添加了一个方向的约束。这里添加的是横向,xml警告纵向也要添加
正确的姿势
假如不利用侧边、基准线等约束条件,控件会跑到(0,0)点
(2) 只有约束控制点和另外一个锚点在同一平面才能创建约束(也就是说将要创建的约束的View和锚点View属于同一级)。因此一个View的垂直平面(左侧和右侧)只能被另一个的垂直平面约束,基线只能被其他基线约束。
(3) 一个约束控制点,只能被用来创建一次约束,但是可以在同一锚点创建多个约束(来自不同的View)
同一锚点有多个约束
-
生成约束实例
1) 为了生成ImageView和父ConstraintLayout之间的约束,点击并拖动ImageView的锚点至布局的边缘,当锚点变为绿色时,松开鼠标就会生成一个约束。这里ImageView与ConstraintLayout建立关联之后,距离ConstraintLayout顶部16dip
和布局的侧边建立联系
2) 为了在两个TextView之间生成约束,点击并拖动被约束TextView的锚点至另一个TextView的锚点处。
和其他控件的侧边建立联系
3) 为了在两个TextView之间生成文字基准线,将鼠标选中TextView并放置在被约束TextView基准线附近,等待其变高亮,然后点击基准线锚点并拖动至另一个TextView的基准线锚点使其连接。
和其他控件的基准线对齐
4) 你也可以添加一个垂直或者水平的辅助线,该辅助线对用户不可见,但是却有助于约束的连接。为了生成辅助线,在布局的任何地方右键并点击Add Vertical Guideline或者Add Horizontal Guideline。
辅助线
5) 如果你为控件添加相反的约束,那么连接的直线就会变成波浪线,就像两个相反的力。这里不是描述一个具体的位置,而是一个百分比,也就是哪里百分比越大,越往哪个方向偏。例如,如果你为ImageView添加一个到布局左右边界的约束,那么ImageView就会默认左右各占50%,水平居中显示。 同理如果你上下左右4个方向都有约束,那么ImageView就全屏居中了
左右约束
6) 删除约束,只要点击连接线的任意一端即可删除。
删除约束
属性面板
当我们点击一个控件的时候,你会发现属性面板右上角多了一个四方块,这个四方块就是控件的一些属性,包括宽高,比例等。仔细的你会发现有三种不同的线类型

Wrap Content:此选项与wrap content作用相同

Any Size:此选项让控件占用所有可用空间以适应约束,与match_parent相似,但是不同之处在于后者是占据父View的所有可用空间。注意ConstraintLayout中不要使用match_parent,要使用0dp才能达到效果

Fixed:此选项允许你给控件高和宽指定具体指

xml代码的学习
刚才的拖拖拽拽是不是很爽?我们切换回TEXT页签来看看代码部分。不知道你有没有注意到ConstaintLayout的自定义布局标签都是以layout_constraint开头的,那么重点部分自然在后面那部分了,简单的说他们的关系是这样的
layout_constraint[当前控件被约束属性]_[参照控件属性]="[参照控件]"
用刚才的xml来举个简单的例子
app:layout_constraintLeft_toLeftOf="parent"
当前控件的左边部分需要与父控件ConstraintLayout的左边部分对齐,从而达到被父控件“约束”的效果。
诸如其他约束部分xml代码,我就简单举几个例子,相信大家结合布局管理器就能够明白了
app:layout_constraintBottom_toBottomOf="@id/constraintLayout" 本控件的底部与ID为constraintLayout的控件底部对齐
app:layout_constraintStart_toEndOf="@id/cancel_button" 本控件的左边界与ID为cancel_button的右边界对齐
app:layout_constraintHorizontal_bias="0.25" 本控件在X轴1/4的地方开始
app:layout_constraintVertical_bias="0.25" 本控件在Y轴1/4的地方开始
app:layout_constraintBaseline_toBaselineOf="@id/cancel_button" 本控件的基准线与ID为cancel_button的基准线对齐
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="72dp"/>
引导线为垂直方向距离左边距72dp
app:layout_constraintGuide_end="92dp" 引导线距离右边距92dp
app:layout_constraintGuide_percent="0.76" 引导线距离左边距百分七十六
app:layout_constraintDimensionRatio="4:3" 在宽或者高为0dp的情况下,表示宽高的横纵比
后记
在使用过程中,我个人感觉Android将来布局方向可能更接近IOS的AutoLayout模式,毕竟拖拖拽拽比现在哼哧哼哧的写xml要方便很多,这也是Google推出ConstraintLayout的原因吧。但是目前版本的ConstraintLayout在使用过程中还是让人很不爽的,比如这个锚点过小,拖拽不容易准确之类的,时不时还要放大布局的比例等。想要替代传统xml布局控件,未来还有很多路要走,但是方向是好的,咱们也要多多支持下
参考文章
2016年Google IO最新布局ConstraintLayout
抢先体验ConstraintLayout以及AS 2.2
代码实验室--带你一步步理解使用 ConstraintLayout
网友评论