[译] 通过ConstraintLayout构建灵活的布局

官网地址
ConstraintLayout 提供了一种不使用嵌套的 ViewGroup 而创建复杂布局的方式。它和 RelativeLayout 相类似,根据兄弟视图和在父视图中的相对位置进行布局,但是,它更加的灵活,在Android Studio 布局编辑器的帮助下,也更加容易。
ConstraintLayout 中所有的功能,都可以借助布局编辑器中的可视化工具直接操作。因为布局 API 和布局编辑器中的实现构成了一一对应的关系。因此,你完全可以借助布局编辑器,在使用 ConstraintLayout时,随意地进行拖拽控件而不是在XML中编辑。
ConstraintLayout 在Android2.3(API level9)或者更高版本的兼容库中是可用的。

Constraints 概述

为了定义一个 ConstraintLayout 中 view 的位置,你必须确定这个 view 在水平和竖直方向的约束。 每个约束代表着一个到其他 view、父控件布局、或者不可见基线的连接、对齐。每一种约束定义了 view 在横轴或者纵轴的位置,所以,为了确定 view 的位置,就至少要有两个约束条件,但是,通常,更多的约束是必要的。
当你把一个 view 拖到布局编辑器中,将会处于没有约束的状态。如果一个 view 没有约束,在实际在设备上运行该布局时,这个 view 将会被绘制到[0,0]点,也就是左上角。
在下图1中,在编辑器中的布局看起来很好,但是,在 view C 上缺少竖直方向的约束。那么当在设备上运行时,view C 会在水平方向上和 view A 的左右边缘对其,但是会出现在屏幕的顶部,因为它没有竖直约束。

图1
图1.1

虽然丢失约束并不会造成编译错误,但是布局编辑器会在工具栏中显示这个错误(编辑器右上角)。

在项目中添加 ConstraintLayout

为了在项目中使用它,步骤如下:

  1. 在 build.gradle 文件中,声明了 maven.google.com 库:
repositories {
    maven {
        url 'https://maven.google.com'
    }
}
  1. 同样,在 build.gradle 文件中添加依赖:
dependencies {
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
}
  1. 点击Sync Project with Gradle Files
    现在你可以使用 ConstraintLayout 了。

转换布局

为了把现有布局转换为 ConstraintLayout ,需要这样做:


示意图

新建一个布局

为了使用一个新的 constraint 布局文件,需要:

  1. 在 Project 窗口,点击模块文件夹,选择 File -> New -> XML -> Layout XML.
  2. 输入布局文件的名字,并且,在根标签,设置"android.support.constraint.ConstraintLayout"
  3. 点击 Finish。

添加约束

从 Palette 窗口中拖拽一个 view 到编辑器中。当向 ConstraintLayout 中添加一个 view 时,这个 view 被显示为一个封闭的盒子,它的每个角都有一个正方形的用以调整大小的柄,每一侧都有一个圆形的用以设置约束的柄。
通过点击 view 先选中它,接着,点击选中约束柄然后拖拽线到一个可用的锚定点(另一个 view 的边或者基线)。当释放点击选中状态后,约束将被建立。
当创建约束的时候,注意一下规则:

  1. 每个 view 至少有两个约束:水平和竖直的。
  2. 竖直方向的约束柄只能和竖直方向的锚定点相连,构成约束关系;同理,水平方向只能和水平方向构成约束关系。
  3. 一个约束柄只能构成一种约束关系,但是你可以创建多个约束到同一个锚定点。
    在删除约束的时候,点击约束柄即可。或者通过点击移除所有约束的图标的按钮


    删除按钮

Parent position

约束 view 的一个边到布局容器的边缘。如下图所示,view 左边和父视图边缘相连,同时,还可以使用 margin 定义到父视图边缘的距离。


父视图约束

Order position

在竖直方向或者水平方向上,定义两个视图出现的顺序。
如下图所示,B在A的右边,C在A的下面,然而,这些约束并没有显示对齐关系,所以,B仍然可以上下移动。


相对位置约束

Alignment对齐

将 view 的边缘和另外一个 view 相同的边缘进行对齐。
如下图所示,B的左边和A的左边对齐。当然,也可以拖拽 view 形成偏移。

左对齐和左对齐偏移

如果你希望两个 view 中间对齐,需要在 view 的两侧都使用约束。


居中对齐

Baseline alignment基线对齐

一个 textview 的基线和另外一个 textview 的基线对齐。

如下图所示,B 的第一行和 A 的第一行对齐。为了使用这种对齐方式,选中 view 后,下面会出现基线按钮
点击它,textview 的基线就会出现。接着,点击这个基线然后拖拽到另外一个基线上,就实现了基线对齐。
基线对齐

Constraint to a guideline 指导线约束

可以添加一个竖直方向或者水平方向的指导线来约束 view 。
指导线对于用户来说是不可见的,指导线可以相对于布局容器边缘的dp值或者百分比进行放置
在创建指导线的时候,可以右键选择创建水平或者竖直指导线,也可以在工具栏中选择创建指导线的按钮。

调整约束偏移

如果在一个 view 的两边,同时使用约束,view 默认在这两个约束之间的偏移是 50%(居中),你可以拖拽 view 或者调整偏移量属性的方式来改变这个值(实际上是调整居左居右的百分比)。


调整约束偏移量属性

调整 view 的大小

可以通过调整 view 四个角的柄在重置 view 的大小。但是,这是一种对大小的硬编码,不能够完成在不同屏幕上的适配。实际上,我们可以更加灵活地处理这一点。
如下图所示,

3 所标注的符号,代表着大小模式,通过点击该符号,可以切换不同的大小模式:


Wrap Content

当符号切换到这方形状,代表设置该 veiw 的wrap content 属性。

Match Constraints

相当于我们对 view 设置了match parent。不同的是,此时 view 大小的是在两个约束之间充满(注意,需要将长度设置为0dp),而一般布局中match parent将充满父控件。如果只有一边有约束,view 的大小将扩充以满足自身需求。


固定大小

此时对 view 设定固定大小是有效的。

设置宽高比率

至少在一个方向上(水平或者竖直方向)设置了 "match constraints",才能够设置宽高比。为了使用这个功能,需要点击上面图10当中的1号图标的标注,然后输入宽高比。


使用 链 来控制线性组

一个链,是一组使用双向位置约束的 view 相互连接构成。


水平链

我们可以使用链来控制一组水平或者竖直方向的 view 的分布方式,有以下几种:

  1. Spread:所有的 view 均匀分布。这是一种默认的方式。
  2. Spread inside:第一个和最后一个 view 分别靠着约束的两边,剩下的 view 均匀分布。
  3. Weight:当对一个链使用 spread 或者 spread inside 时,如果将一个或者多个 view 设置为 match constraints(即在水平或者竖直方向上设置为0dp),这些 view 将填充剩余的空间。默认的,空间被均匀分发给各个 view ,但是可以通过指定占比的方式改变这种行为,即通过改变layout_constraintHorizontal_weight 和layout_constraintVertical_weight 属性(注意,这里的属性前缀设置app,即app:layout_constraintHorizontal_weight="1",而不是android)。如果你熟悉线性布局中的 layout_weight ,上面属性的工作方式和 layout_weight是一样的。因此,如果 view 有最高的比重,它将得到最大的空间。如果 view 拥有相同的比重,将获得相同的空间。
  4. Packed:view 将被打包在一起(在指定了margin属性之后)。接着,你可以通过改变左边第一个 view 偏移的方式调整被打包的整条链的偏移。
    为了能够快速创建一个链,首先需要选中要放入链中的 view,然后在 view 右键单击,接着选择对话框中的 Center Horizontally 或者 Center Vertically,来创建一个水平或者竖直方向的链。


    创建链

自动创建约束

还可以将每个 view 放在你期望的位置上,然后点击 Infer Constraints 符号来自动创建所有约束。

Infer Constraints

Infer Constaints 会扫描布局,对所有 view 推断并使用一种最高效的方式来构建约束。

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

推荐阅读更多精彩内容