使用 ConstraintLayout 来设计 View

本文翻译自:https://codelabs.developers.google.com/codelabs/constraint-layout/index.html?index=..%2F..%2Findex#0
目前ConstraintLayout还处于beta版。

1. 概要

ConstraintLayout.png

ConstraintLayout 是 Android Support 库中可用的一种新型的建立在灵活的约束系统上的布局。在文末你将学会利用布局编辑器来构建相对复杂的布局。

  • ConstraintLayout使用新的布局管理器
  • 创建约束来实现灵活高效率的布局
  • 新的布局编辑器的多种特性。

需要的环境:AndroidStudio 2.2

2. 获取示例代码

示例代码下载地址
或者从github上clone代码:
$ git clone https://github.com/googlecodelabs/constraint-layout.git

constraint-layout 的仓库包含一个项目:

**constraint-layout-start **— Project that contains the layouts that you'll build upon in this codelab.

3. 运行示例代码

首先,来看一下运行后的程序是怎样的。请确保您的Android Studio在版本2.2以上。

  • 进入 File > New > Import Project 并且从之前下载的示例程序中选择路径 constraint-layout-start.
  • 点击 **Gradle sync ** 按钮.
  • 从项目面板中打开 res/layout/activity_main_done.xml.
  • 选择 tab Design 可以看到最终的布局.
  • 在 UI Builder的左上方变换虚拟设备等按钮可以看到不同因素影响下渲染的布局.

4. 约束系统概览

布局引擎使用为每个小部件指定约束来确定它们在布局中的位置。 您可以手动或通过Android Studio布局编辑器中的推算自动指定约束。 为了更好地理解约束,让我们看看所选窗口小部件上的基本处理。

约束

约束可帮助您保持小部件对齐。 您可以使用锚点(例如下面描述的约束句柄)来确定各个窗口小部件之间的对齐规则。 例如,将约束从按钮2的左约束句柄(参见下面的图A)设置到按钮1的右约束句柄意味着按钮2小部件将位于按钮1的右边56dp。

Figure A.png
不同类型的句柄
FigureB.png

在这张图上,我们可以看到不同类型的句柄。

Resize Handle:类似于你可能已经使用的其他设计/绘制应用程序,
Resize Handle允许您调整窗口小部件的大小。

Resize Handle.png

Side Constraint Handle: 侧边约束句柄(每个小部件侧面的圆形)允许您指定该窗口小部件的位置。 例如,您可以使用窗口小部件的左侧约束句柄总是在另一个窗口小部件的右侧的24dp。 这些在整个编码表中也被称为锚点。

Side Constraint Handle.png

Baseline Constraint Handle:
基线约束句柄帮助您对齐任何两个小部件的文本字段,而不考虑小部件大小。 对于当你有两个不同大小的小部件,但希望里面的文本是对齐的情况是很有帮助的。

Baseline Constraint Handle
Baseline Constraint Handle

约束系统的规则
布局中的窗口小部件的锚点可以连接到另一个窗口小部件的任何锚点,但以下情况除外:
不能连接不同类型的锚点:

  • 锚点在不同轴线上,如左,顶锚点连接。
  • 基线约束句柄只能限制到另一个基线。
    不允许连接导致循环的锚点。

5. 构建初始应用程序

准备工作:

  • 从左侧导航栏中打开 res / layout / activity_main_start.xml
  • 包括对约束布局的依赖
    约束布局作为一个单独的支持库,可以在所有Android版本(Android 2.3(Gingerbread)以上)运行。
    应用程序已经在app / build.gradle中包含了该依赖关系。 对于您打算使用ConstraintLayout构建的应用程序,添加以下编译依赖关系:
dependencies {
  ...
  compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha2'
}````
* 导航到  ````res/layout/activity_main_start.xml````

布局的XML版本已经在codelab项目中包含一个空的ConstraintLayout元素。 ConstraintLayout是从头开始构建的,以便与UI Builder结合使用,因为我们相信它可以提供更直观和更强大的体验。 尽管如此,您仍然可以访问并可以编辑相应的XML。(这间接告诉我们他是一个ViewGroup)

```` xml
<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</android.support.constraint.ConstraintLayout>
  • 切换到(在编辑器窗口底部显示为选项卡的)设计(Design)视图。(好拗口)
  • 为布局添加一个ImageView
    第一个任务是将ImageView添加到布局。 在设计窗口中,在面板上找到ImageView并将其拖动到布局中。

一旦ImageView被拖动到布局里,UI Builder会要求使用一个资源。 constraint-layout-start sample已经包括使代码方便实现的资源。 继续选择@drawable/singapore资源。

选择后,ImageView将出现在布局上,您可以单击并按住角落以调整图像大小,如“约束系统概述”中所述。

https://codelabs.developers.google.com/codelabs/constraint-layout/img/e499748f0aace62e.png
https://codelabs.developers.google.com/codelabs/constraint-layout/img/e499748f0aace62e.png
  • 在布局里添加TextView
    现在,从面板里拖一个TextView到布局里。

我们在UI Builder中看到一些警告,这是由于缺少ImageView上的contentDescription属性,以及对TextView硬编码文本。 内容描述属性对于构建可访问应用程序很重要。
对于这个codelab,让我们使用一个已经可用的资源@ string/dummy作为属性。

在右侧,“检查器”窗格允许您更改所选窗口小部件的各种属性。

  1. 选择ImageView并将@ string / dummy添加到其contentDescription属性中。
  2. 在“检查器”窗格中,还可以查看ImageView的其他属性。 出于此Codelab的目的,将scaleType更改为centerCrop。
  3. 接下来,我们选择TextView并使用Inspector窗格将TextView的文本值修改为@ string / singapore。

此时,我们在布局中有两个视图。 在下一节中,我们将了解如何在视图之间创建约束。

前边都是小菜一碟,接下来才是本文的重点,要点,新的知识点。
此处是高贵的分割线。




内容主要涵盖了:

  • 创建手动约束
  • 使用Autoconnect创建约束。
  • 使用推理创建约束。

6.创建手动约束

操作方法: 要创建约束,您需要在给定的句柄上单击并按住鼠标,然后将其拖动到另一个窗口小部件的约束句柄。 一旦锚点为绿色,您可以释放鼠标以完成约束创建。

重要提示:UI Builder会自动启动“自动连接”模式。 由于我们在本节学习手动约束,通过单击操作禁用“自动连接”模式,或确保它已禁用。

此时是禁用状态.png

在我们开始之前,确保我们在布局中有一个ImageView和一个TextView。 我们的目标是在ImageView,容器和布局上已经有的TextView控件之间创建约束。

让我们假设我们想要TextView在我们的最终布局中的ImageView下面。 为了实现这一点,我们可以在TextView的顶部锚点和ImageView的底部锚点之间创建一个约束,如图所示。


https://codelabs.developers.google.com/codelabs/constraint-layout/img/94a8a411756ba1e1.png
https://codelabs.developers.google.com/codelabs/constraint-layout/img/94a8a411756ba1e1.png

删除一个约束
使用布局中显示的icon删除约束按钮删除所选窗口小部件上的所有约束 。
要删除单个约束,请单击设置约束的特定锚点。
如果您要删除整个布局中的所有约束,请使用菜单图标。

就是这个icon
就是这个icon
  • 下一步是在ImageView的顶部锚点到布局的顶部之间创建一个约束。


    https://codelabs.developers.google.com/codelabs/constraint-layout/img/172302f4ec011ef5.png
    https://codelabs.developers.google.com/codelabs/constraint-layout/img/172302f4ec011ef5.png

注意:在XML代码中,ImageView有错误提示:
****The view is not constrained vertically: at runtime it will jump to the left unless you add a vertical constraint.****
也就是说,手动将ImageView拖动到中央是无效的,必须声明一个垂直居中的约束。

最后,我们还可以使用左右约束将ImageView锚定在布局的中心。


https://codelabs.developers.google.com/codelabs/constraint-layout/img/89f057b3a8ea3e0b.png
https://codelabs.developers.google.com/codelabs/constraint-layout/img/89f057b3a8ea3e0b.png

上述操作导致了如下错误:

此时出现了错误,效果也不是预想的.png

原因是没有一个组件的ID是constraintLayout。
将文件中的根View,ConstraintLayout,的id设置为constraintLayout即可。

本节介绍了如何通过拖动连接线来创建窗口小部件之间的约束的基础知识。 此时,您可以通过添加其他元素来浏览视图和UI Builder。 在下一节中,我们将了解检查器。


7. 熟悉 Inspector

在本节中,我们来看看视图检查器。 检查器位于UI构建器的右侧。 除了列出所选窗口小部件的各种属性之外,它还显示视图如何对齐和任何约束。

继续并从布局中删除TextView。
在ImageView的底部锚点和容器底部之间创建约束。
UI构建器应如下所示。

上述 action 示例.png

检查器在方块中心显示该ImageView。以下部分描述了各种元素及其用途。

边距:在窗口小部件之外的左,右,顶部和底部是边距。您可以通过单击值并将其设置为不同的值来更改边距。在上面的屏幕截图中,边距设置为16dp。

删除约束:在检查器中单击将窗口小部件连接到容器的线,还可以选择删除约束。注意,删除约束也可以通过点击现有约束句柄来完成。

定位窗口小部件:当窗口小部件上至少有两个相对的连接(例如顶部和底部,或左右)时,您可以看到一个滑块,可以调整窗口小部件沿着轴。这也称为水平或垂直偏置。您可以调整水平和垂直偏置并更改方向以查看偏置是否保持不变。或者,这也可以通过将小部件移动到期望的位置来实现。

继续,将垂直偏压改为75%,将水平偏压改为75%。下面的图片可以作为指南。

https://codelabs.developers.google.com/codelabs/constraint-layout/img/9a902a1d69ff5d97.png
https://codelabs.developers.google.com/codelabs/constraint-layout/img/9a902a1d69ff5d97.png

在安卓Studio 2.2版本上,Properties下方还有一个View all Properties的按钮。可以看到更多属性。

这张图有点大.png

控制窗口小部件的内部尺寸:窗口小部件中的内部线条可让您控制尺寸。 您可以单击特定行以查看它的操作。

这是“检查器”窗格中窗口小部件的放大视图。 单击检查器窗格小部件的内部线将循环选择下面提到的选项。

fixed.png

Fixed: 此选项允许您指定窗口小部件的宽度/高度。

anysize.png

AnySize: 这个选项让部件占据所有可用的空间以满足该约束。换而言之,这有点像match 约束。但是这与占据父View所有的空间的match_parent有所不同。

wrap_content.png

Wrap Content: 此选项仅扩展为用所包含的元素(如文本或drawable)填充窗口小部件。


AnySize独立于容器。 如果ImageView被约束到一个按钮,AnySize只会展开它,以适应按钮。(图文搭配阅读可有深刻体会)
Figure A
Figure A

Figure A:在'AnySize'应用于其宽度之前显示ImageView。
Figure B
Figure B

Figure B: 在'AnySize'应用于其宽度之后显示ImageView。

要查看和编辑给定窗口小部件的所有其他属性,请单击属性窗格右上角的icon,上述已经讲过这些。

在本节中,我们探讨了检查器。 检查器的目标是让您在不离开UI构建器的情况下编辑所有属性和约束。

8.使用自动连接创建约束

自动连接,顾名思义,自动创建小部件之间的连接。 理解Autoconnect功能尝试创建到相邻小部件的连接非常重要。

在开始使用本节之前,请确保:

  • 从“项目”窗格中打开res / layout / activity_main_autoconnect.xml。 确保选择“设计”选项卡。
  • 自动连接已启用
启用自动连接

接下来,我们选择ImageView,并通过拖动它在布局中居中,直到指南显示。 在它居中后几秒钟,自动连接开始,并创建与容器的顶部,左侧,底部和右侧的约束,如下面的动画所示。

https://codelabs.developers.google.com/codelabs/constraint-layout/img/ef55af9bc16f1492.png
https://codelabs.developers.google.com/codelabs/constraint-layout/img/ef55af9bc16f1492.png

这里我们在布局上有一个ImageView,我们看到Autoconnect如何创建约束。


https://codelabs.developers.google.com/codelabs/constraint-layout/img/10210fd273ea1a86.png
https://codelabs.developers.google.com/codelabs/constraint-layout/img/10210fd273ea1a86.png

以下是本节下一部分的步骤。为了指导,上面的动画显示了下面使用的步骤:

  1. 对齐要放置在顶部的ImageView,并使用检查器(AnySize)确保它展开以填充父级的宽度。
  2. 在布局的右下角放置两个按钮。使用检查器窗格将最右侧按钮的文本属性更改为@ string / upload,将其左侧的文本属性更改为@ string / discard。
  3. 从调色板中拖动TextView和纯文本,并将它们放置在布局上。
    将TextView和纯文本字段调整为相差48dp。几秒钟后,Autoconnect将为窗口小部件创建约束。
  4. 同样选择上传按钮,并将其放在靠近我们的右边距,我们让Autoconnect做剩下的事情。
  5. 最后,将discard按钮32dp远离upload按钮。

作为练习,也移动TextView 48dp下面的ImageView。要做到这一点,选择TextView并移动,直到它的48dp下面的ImageView。

重要的是要理解Autoconnect仅为当前移动的窗口小部件创建约束。

自动连接通过连接到最近的小部件来帮助您,这在许多情况下是有帮助的。有些情况下,Autoconnect不能实现所需的行为,开发人员应该使用手动约束或推理来构建他们的ConstraintLayout。推论将在代码实验室的下一步中讨论。

9.使用Inference创建约束

Inference引擎通过在布局中添加的元素之间创建约束来帮助开发人员。 Inference创建的约束取决于添加到布局的元素的类型及其大小。

推理和自动连接有什么区别?
推理引擎在布局中的所有元素之间创建约束,而Autoconnect在相邻元素之间创建约束。
自动连接的目的是创建约束来布置正在操作的窗口小部件,即其他窗口小部件不会被约束到您正在移动的窗口小部件,但是您移动的窗口小部件将被限制到其他窗口小部件。 这是一个重要的区别,因为它意味着自动连接不会修改您的当前约束。

setup
对于这一步,我们从layout/activity_main_inference.xml布局开始。 在设计视图中打开布局文件。 默认情况下,此文件中的布局定义以下内容:

  • @drawable/singapore和@drawable/ic_star的ImageViews。 ic_star图像已经被约束为具有81%的垂直偏差。 您可以通过选择包含ic_star的ImageView的垂直偏置,并检查前面讨论的检查器。
  • 大ImageView的底部锚点(@drawable/singapore)被约束到ic_star ImageView的底部锚点,边距为16dp。
  • 除了ImageView之外,还有TextViews for Camera,Settings和ImageView的字幕。

你会学到什么

  • 使用菜单上的操作水平和垂直扩展视图。
  • 使用inference按钮帮助使用inference创建约束。

了解UI Builder图标操作
由于我们将使用一些这些选项,来看看UI Builder上可用的操作。

删除所有约束
使用inference创建约束,inference引擎尝试基于各种因素(例如窗口小部件的位置及其大小)找到并创建最佳连接。
水平扩展窗口小部件以满足约束。
垂直扩展窗口小部件以满足约束。

添加占用可用空间的TextView
我们的目标是为图像的描述添加一个TextView。 我们已经有一个跨越多行的@string/singapore_description。

  • 首先,从调色板中拖动一个TextView,并将其放在设置文本视图下面。
  • 使用操作水平扩展视图以匹配准则。
  • 使用操作垂直扩展以填充可用的垂直空间。


使用 Inference操作
既然你在布局中有TextView,你就可以看到操作中看到Inference。
单击推断constraints 操作以使用推理创建约束。
Inference引擎在布局中的所有视图之间创建约束。 您的最终布局应如下所示:

最终布局

创建约束后,您可以通过单击UI Builder左上角的按钮来修改“要渲染的虚拟设备”。 选择其他设备(如Nexus 6P或Nexus 9),以查看布局是否正确呈现。

您现在已经看到了使用约束系统的全部范围:使用Inference引擎创建手动约束,使用自动连接的约束和约束。

自动连接和推理帮助您通过布局引擎找出如何为您的UI的各种元素创建约束。 然后,您可以自由地进一步修改由自动连接或推理引擎创建的约束。

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

推荐阅读更多精彩内容