ConstraintLayout 使用指南

ConstraintLayout 是什么

ConstraintLayout 是在2016年的 Google I/O 大会上推出的一种新型布局方式-约束布局,它可以灵活的控制组件在布局中的位置和大小,Google 为约束布局提供了配套的视图编辑器,让我们可以在可视化的界面中以拖拽的方式进行布局。可以认为 ConstraintLayout 是升级版本的 RelativeLayout,在相对布局的基础上,增加了比例这一概念,在下面的代码中将为大家详细介绍这一概念。

以下,我将会用 RL 表示RelativeLayout,CL 表示 ConstraintLayout,LL 表示 LinearLayout

我的环境

  • Android Studio 版本:2.3
  • ConstraintLayout 版本:com.android.support.constraint:constraint-layout:1.0.2

ConstraintLayout XML 属性

从 Android Studio 2.3 版本开始,我们创建新的布局会发现,默认的根布局已经变成了 CL

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.xiezhen.practice.DefaultActivity">
    
</android.support.constraint.ConstraintLayout>

接下来,将 CLRL 的属性进行比较,在了解了 CL 的基本属性后,将为大家介绍视图编辑器的中的各种操作,我会选择几种特有的操作进行讲解,相似的操作,大家可以自行练习

ConstraintLayout 和 RelativeLayout

--- CL RL
与目标组件左对齐 layout_constraintLeft_toLeftOf layout_alignLeft
在目标组件的右边 layout_constraintLeft_toRightOf layout_toRightOf
与目标组件右对齐 layout_constraintRight_toRightOf layout_alignRight
在目标组件的左边 layout_constraintRight_toLeftOf layout_toLeftOf
与目标组件上对齐 layout_constraintTop_toTopOf layout_alignTop
在目标组件底部 layout_constraintTop_toBottomOf layout_below
与目标组件下对齐 layout_constraintBottom_toBottomOf layout_alignBottom
在目标组件的上部 layout_constraintBottom_toTopOf layout_above
与目标组件基线对齐 layout_constraintBaseline_toBaselineOf layout_alignBaseline

如上表格所示,RL的属性,CL都有,只不过在属性中多了 constraintXXX,这个部分,这部分代表 View 的边,表示View的上,下,左,右或者基线,只不过在RL中这一部分省略掉了。

在RL中,我们可以相对于父布局进行布局,例如将一个按钮与父布局的上边和左边对齐,XML 的布局代码是这样的:

相对布局父布局依赖
相对布局父布局依赖

在CL中是这样的:

约束布局父布局
约束布局父布局

两种方式呈现的结果都是一样的:

父布局依赖
父布局依赖

ConstraintLayout 的比例

RelativeLayout 中,我们可以使用以下三种属性来指明组件在父布局中垂直居中,水平居中或者居中

对齐属性
对齐属性

CL 中是这么做的
水平居中,建立与父布局左边和右边的依赖

水平居中
水平居中

垂直居中,建立与父布局上边和下边的依赖

垂直居中
垂直居中

下面的代码展示了一个居中的按钮

按钮居中.png-167.5kB
按钮居中.png-167.5kB
按钮居中效果.png-30kB
按钮居中效果.png-30kB

现在来讲点和 RL 不同的东西,目前为止我们展现的效果都是 RL 或者 LL 可以实现的,让我们看看 CL 的这两个属性,这两个属性的取值范围都是[0,1]

  • layout_constraintHorizontal_bias
  • layout_constraintVertical_bias
    其实从属性名我们也可以猜出它的作用,可以认为是在水平方向或者竖直方向上偏移的百分比,上图展示的按钮居中,是因为默认的bias属性值为0.5,下面我们改变这两个属性值,将横向的 bias 改为0.9,垂直的 bias 改为 0.1,效果如下:
Bias.png-89.6kB
Bias.png-89.6kB
Bias 效果.png-35.5kB
Bias 效果.png-35.5kB

ConstraintLayout 的尺寸

不同于其他组件,CL 内 View 的 layout_height 和 layout_width 有以下三种取值方式

  • 指定一个具体指
  • 使用 WRAP_CONTENT
  • 使用 0dp,等价于 MATCH_CONSTRAINT属性

注意:没有 MATCH_PARENT 属性,我们要注意约束的概念 0dp 就代表我们的宽高将充满约束,而不是充满父布局,举个例子,我们将中间的 Button 的顶部与上方 Button 的底部约束,将中间 Button 的底部与下方 Button 的顶约束,并且将高度设置为 0dp, 期待的表现是高度充满整个约束,效果如下:

CL 尺寸.png-221.4kB
CL 尺寸.png-221.4kB
CL 尺寸效果.png-31.1kB
CL 尺寸效果.png-31.1kB

ConstraintLayout 的宽高比

以前我们经常有需求,需要满足一定宽高比的 ImageView ,CL 给我们提供了易用的属性 layout_constraintDimentionRatio 我们只需要按照 width:height 的形式填写属性值就可以了,需要注意的是layout_height,layout_width 两个属性至少有一个属性值为0dp,如果两个都是 0dp,则需要指定一个受限制的边如下图,"h,11:3",意味着高度受限,按照宽高比11:3的比例跟随宽度进行变化

CL 宽高比.png-200.2kB
CL 宽高比.png-200.2kB
CL 宽高比效果.png-35.9kB
CL 宽高比效果.png-35.9kB

ConstraintLayout chain

约束链,可以在垂直或者水平方向上提供群组行为,什么样的约束可以构成一条约束链,View 之间相互约束就可以形成链,例如下图展现一条最小的链,Button1 的底部和 Button2 的顶部相互约束

CL Chain.png-180.4kB
CL Chain.png-180.4kB
CL Chain 效果.png-35.8kB
CL Chain 效果.png-35.8kB

约束链的几种形式

  1. spread:视图均匀分布
  2. spread_inside :chains 中头部和尾部的视图将会将会贴在各自的约束上,其余视图将会均匀分布
  3. spread_with_weight:在spread 或者 spread_inside 模式中,你可以像指定 LinearLayout 的 layout_weight 属性一样来设置 CL 的 layout_constraintVertical_weight 来达到和 LinearLayout weight的同样的效果
  4. packed:将视图打包在一起,默认居中,我们可以通过改变 chains 的 bias属性值,来调整整条链的偏移位置

chain,可以让我们很轻松的完成线性布局可以完成的事情,并且更方便特性更强大,盗用一张官网的图帮助理解 chains style:

CL Style.png-14.6kB
CL Style.png-14.6kB

spread

spread
spread

spread_inside

spread_inside
spread_inside

spread_with_weight

spread_with_weight.png-25.8kB
spread_with_weight.png-25.8kB

packed

packed.png-26.9kB
packed.png-26.9kB

packed bias

packed bias.png-21.9kB
packed bias.png-21.9kB

GuideLine

可以认为是辅助线,作用如其名了,我们可以在容器的水平或者竖直方向插入一条辅助线,容器内的 View 都可以和辅助线建立约束,这个特性非常好用,我们先来看看 GuideLine 的几个属性

  • layout_constraintGuide_begin 指定辅助线距离容器顶部或者左边的距离
  • layout_constraintGuide_end 指定辅助线距离容器底部或者右边的距离
  • layout_constraintGuide_percent 指定容器的宽或者高度的百分比

下面这个效果应该很常见,在中间插入一条垂直方向的 GuideLine,然后分别在 parent 右侧和 GuideLine,parent 左侧和 GuideLine 之间建立约束:


CL GuideLine.png-227.5kB
CL GuideLine.png-227.5kB

Cl GuideLine 效果.png-29.9kB
Cl GuideLine 效果.png-29.9kB

一些补充

  • Percent
  • Group
  • Barriers

Percent

百分比布局,我们可以很容易的在 CL 中使用百分比布局,代码如下,将 layout_constraintHeight_default 设置为 percent 即采用百分比的方式布局,然后设置 layout_constraintHeight_percent 的属性值,来改变垂直方向的百分比,设置宽度百分比相同。

百分比
百分比
百分之效果
百分之效果

Group

通过 constraint_referenced_ids 属性来指定 Group 包裹的 View,对这些 View 提供统一的可见性设置,目前感觉比较鸡肋,本来我以为可以使用 Group 来提供背景色的设置,或者其他群组行为,但是很可惜,目前提供的群组行为只有可见性而已

Group.png-73.2kB
Group.png-73.2kB
Group Visible 效果.png-28.6kB
Group Visible 效果.png-28.6kB

然后将 visibility 属性设置为 Gone ,可以看见两个 Button 的约束,变成了一条 Group 约束。

Group Gone 效果.png-25.1kB
Group Gone 效果.png-25.1kB

Barriers

Barriers 可以理解为,在一组视图指定的边上创建一条 GuideLine。

  • constraint_referenced_ids属性,指定引用的视图组
  • barrierDirection属性,指定边(Barriers 的方向),有以下6种可选值 start,left,top,end,right,bottom。

如下图所示,有的时候我们可能会有类似的需求,左右两部分,左侧部分是 Title 和 Content,右侧为图像或者其他内容,如果采用 LL 和 RL 嵌套的方式,很容易解决,如果使用 CL 布局的话,我们就需要使用 Barrier 这个新特性来进行布局,在 Title 和 Content 指定为 Barrier 的引用试图组,然后在组的右边设置一条 Barrier,将图片与Barrier建立约束即可,如果不采用 Barrier ,而是直接让图片与 Title 或者 Content 建立约束,都有可能产生重叠的影响

采用 Barrier

Barrier 效果.png-22kB
Barrier 效果.png-22kB
Barrier.png-105.2kB
Barrier.png-105.2kB

不采用 Barrier

No Barrier.png-62.3kB
No Barrier.png-62.3kB
No Barrier 效果.png-21.7kB
No Barrier 效果.png-21.7kB

总结

CL 还是很容易上手的,提供的各种特性比较强大,本文虽然是采用的 XML 的形式来介绍,但其实 CL 用视图编辑器,直接采用拖拽的方式更加的便捷,CL确实是减少了视图层级,但是有没有带来效率上的提升,就见仁见智了,到底在多复杂的布局情况下适合采用 CL 官方也没有给出明确的说法,在我测试的几个布局中,CL 的性能都没有超过 RL。另外 CL 毕竟发布只有一年,个人感觉还有很多特性不够成熟,例如 Group 的特性居然只能够改变群组可见性,Barrier的特性明明可以和 Group 结合到一起,我相信CL之后会原来越完善😳。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容