在此 Codelab 中,您将学习如何将 Android Studio Layout Editor 与 ConstraintLayout 结合使用,后者是 Android 支持代码库中用于构建灵活、高效布局的一种新类型布局。Layout Editor 使用约束条件来确定界面元素在布局中的位置。约束条件表示与另一个视图、父布局或不可见参考线的连接或对齐方式。

您在此 Codelab 中主要使用 Layout Editor,而不会直接编辑 XML 或 Java 代码。在此 Codelab 结束时,您将具备使用 Android Studio Layout Editor 的足够经验,能够构建如下所示的复杂布局。

您将学习的内容

您需要具备的条件

如何使用本教程?

仅阅读其内容 阅读并完成练习

如何评估您构建 Android 应用的经验?

初学者 中等程度者 专家

要下载示例应用,您可以执行以下操作之一:

下载ZIP

...或从命令行使用下列命令克隆 GitHub 代码库:

$ git clone https://github.com/googlecodelabs/constraint-layout.git

常见问题解答

首先,让我们看一看已完成示例应用的外观。按照下列说明在 Android Studio 中打开示例应用。

  1. 如果已下载constraint-layout-master zip 文件,请将其解压缩。
  2. 打开constraint-layout-master文件夹可以看到constraint-layout-start文件夹。
  3. 在 Android Studio 中打开constraint-layout-start项目。
  4. 点击Run按钮,然后选择模拟器或者连接必须能够运行 Android Lollipop(支持的最小 SDK 为 22)的 Android 设备。您将看到 constraint-layout 屏幕:

为了使用 ConstraintLayout,项目的build.gradle (Module: app)文件中必须包含相应的支持内容库。constraint-layout依赖项作为单独的支持内容库提供,此内容库可以在 Android 2.3 (Gingerbread) 及更高版本上运行。

初学者应用已在build.gradle.中包含此依赖项。Android Studio 模板也包含此依赖项,以用于新项目。

创建新的应用项目时,请始终打开build.gradle并检查是否包含了此依赖项的最新版本。Android Studio 将突出显示并非最新版本的任何依赖项。如果系统突出显示此依赖项,请将鼠标指针悬停在语句上,Android Studio 将向您推荐一个更高版本。将x.x.x替换为建议的版本号。

dependencies {
  ...
  compile 'com.android.support.constraint:constraint-layout:x.x.x'
}

如果您看到 Gradle 同步错误消息,请确保build.gradle中的buildToolsVersion语句设置为 25.0.3 或更高版本。

buildToolsVersion "25.0.3"

错误消息通常包含用于帮助下载构建工具版本的链接。

Android Studio 提供用于快速构建布局的 Layout Editor。通过此工具,您可以将界面元素拖动到视觉设计和蓝图视图中,在布局中放置元素,添加约束条件以及设置属性。快来了解一下吧:

  1. 从 Project 窗格中打开activity_main_done.xml。这将打开 Layout Editor。
  2. Design标签应处于已选中状态,否则请点击Design标签。

  1. 如果没有蓝图,请点击工具栏中的 Show Blueprint 图标

您的 Layout Editor 窗格看起来应如下所示。

上图显示了 Layout Editor 的组件:

  1. 工具栏
  2. Palette
  3. Design 视图
  4. Blueprint 视图
  5. Component Tree

点击工具栏中的Device in Editor按钮(在上图中显示为),以选择不同的设备并查看布局在不同设备屏幕上的外观。

要查看布局的 XML 代码,请点击 Design 标签旁边的Text标签。您可以看到布局中每个元素的 XML 属性。例如,下图显示 Design 视图中包含约束条件的EditText元素,Text标签显示该EditText元素的 XML 约束条件属性。

Design 视图中的EditText元素:

XML 格式的EditText元素如下,仅显示了约束条件属性:

<EditText
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        ...
        app:layout_editor_absoluteX="73dp"
        app:layout_editor_absoluteY="176dp"
        app:layout_constraintLeft_creator="1"
        app:layout_constraintTop_creator="1"
        app:layout_constraintRight_creator="1"
        app:layout_constraintLeft_toLeftOf="@+id/settings"
        tools:layout_constraintLeft_creator="1"
        app:layout_constraintTop_toBottomOf="@+id/title"
        android:layout_marginTop="8dp"
        ...
/>

例如,上述 XML 代码中的app:layout_constraintLeft_toLeftOf属性将该元素的左侧放置在settings元素左边。

Layout Editor 使用约束条件来确定界面元素在布局中的位置。约束条件表示与另一个视图、父布局或不可见参考线的连接或对齐方式。您可以手动创建约束条件(稍后将介绍此内容),也可以使用Autoconnect工具自动创建。

Autoconnect 可以为界面元素创建两个或更多与父布局的约束条件。在将元素拖动到布局中之后,它会根据元素的位置创建约束条件。

  1. 从 Project 窗格中打开activity_main_autoconnect.xmlDesign标签应处于已选中状态,否则请点击该标签。
  2. Autoconnect 工具位于工具栏中。默认情况下,它处于启用状态。对于此练习,请确保此工具处于启用状态。
  3. 在 Blueprint 或预览中,点击ImageView,然后将其向布局中心拖动,直到显示虚参考线为止。
  4. 在您看到从上到下、从左到右的参考线时,松开鼠标按键。您会看到使ImageView位于布局中心的四条蓝色锯齿线,这些锯齿线表示将视图的顶部、左侧、底部和右侧边缘连接到父视图边缘的约束条件,如下方动画图形所示:

由于视图足够靠近中心位置,而使 Layout Editor 认为其应该位于布局中心,因此约束条件将自动添加至视图的所有四条侧边。

在 Blueprint 或 Design 视图中,注意 ImageView 上的以下手柄:

大小调整手柄:您可以拖动方形的大小调整手柄来调整元素的大小。在拖动时,此手柄将变为有角的角点。

约束手柄:点击某个约束手柄(在元素的每条侧边上显示为一个圆圈),然后将其拖动到另一个约束手柄或拖动到父边界,以创建约束条件。约束条件将以锯齿线表示。

要将ImageView对齐到顶部,请选中 ImageView 并将鼠标指针悬停在底部约束手柄上,直到显示提示为止,然后点击底部约束手柄将其删除:

由于只有一个垂直约束条件(位于顶部),因此视图现在已附加到布局顶部。水平约束条件仍保持视图位于布局中间。

在已启用 Autoconnect 的情况下,您可以将任何元素(例如按钮)拖动到布局的任何部分,以生成与父布局的约束条件。要了解其工作原理,请执行以下操作:

  1. 将 Button 从 Palette 的 Widgets 部分拖动到布局中的任何位置,然后松开 Button。

  1. 选中布局中的 Button,并按下图所示将其拖动到右下角,直到显示侧边距和下边距参考线为止。在您看到这两个方向上的参考线时,松开 Button。Button 将自动对齐到参考线。

然后,Autoconnect 将生成与父布局的约束条件。系统会自动添加这两个约束条件,以便确定 Button 相对于父布局的位置。由于您已将 Button 拖动到边距参考线,因此 Layout Editor 将包含匹配默认边距参考线的 16dp 右边距和下边距:

在下一部分中,您将处理界面元素的边距和内部尺寸。

在此练习中,您将通过添加ImageView并调整其大小来从头开始设计布局。

  1. 从 Project 窗格中打开activity_main_start.xml,然后点击Design标签。
  2. 关闭 Autoconnect 工具(点击它一次可显示),以确保添加界面元素时不会自动显示约束条件。

向布局中添加 ImageView

  1. 在 Palette 的 Images 部分中找到ImageView,然后将其拖动到布局中的任意位置。

这将显示Resources对话框。constraint-layout-start示例已包含用于 Codelab 的资源。

  1. 选择@drawable/singapore资源,然后点击OK

ImageView将显示在布局中。

  1. 围绕布局区域拖动元素,然后拖动角点以调整图像大小。通过调整图像大小,宽度和高度将固定为特定尺寸。

您将在Component Tree窗格中看到指示器。点击指示器可查看更多信息。警告和错误包括:

内容描述属性对于构建可访问的应用十分重要。您可以将可用资源@string/placeholder用于此属性。

修改属性

要添加或更改属性值,请使用在 Layout Editor 右侧打开的Attributes窗格:

  1. 如果未选择ImageView元素,请将其选中。
  2. 点击工具栏最右端的Attributes标签:

这将打开Attributes窗格,以便您能够更改所选界面元素的属性。

  1. @string/placeholder添加至contentDescription属性。
  2. Attributes窗格中,您还可以看到ImageView的其他属性。从scaleType下拉菜单中选择centerCrop以更改scaleType属性。

向父布局中添加约束条件

下方的动画图形说明了如何执行这些步骤:

  1. 要向ImageView的左边缘添加约束条件,请点击并按住约束手柄,然后将线拖动到父布局的左边缘。
  2. 要为ImageView添加右边缘约束条件,请将约束手柄拖动到父布局的右边缘。
  3. 要为ImageView添加顶部约束条件,请将约束手柄拖动到父布局的顶部。
  4. 要为ImageView添加底部约束条件,请将约束手柄拖动到父布局的底部。

默认情况下,Layout Editor 将在ImageView四周自动包含 8dp 的边距。边距的大小显示在约束条件线上方:

您将在下一部分中处理边距。

在本练习中,您将继续进行未完成的布局设计,在先前的练习中您已将 ImageView 约束到布局的所有四条侧边。如果activity_main_start.xml尚未打开,请从 Project 窗格中将其打开,然后点击Design标签。

Attributes窗格将在顶部的方块中显示视图检查器,位于srccontentDescriptionImageView属性上方。视图检查器显示界面元素的约束条件和边距,以及用于沿水平轴和垂直轴调整此元素位置的滑块。

在上图中:

  1. 使用此按钮可关闭 Attributes 窗格。
  2. 边距值显示在所有四条侧边上。可以通过点击值并选择另一个值来更改边距。
  3. 内部线表示受限宽度和长度。
  4. 使用滑块可以通过相对约束条件来更改元素的水平和垂直约束条件偏差。

使用约束条件偏差确定元素的位置

在先前的练习中,您已将 ImageView 约束到布局的所有四条侧边。其结果是,元素在布局中的水平和垂直方向上居中。元素与布局边框之间的间距度量称为约束条件偏差。如果元素居中,其约束条件偏差为 50%,这表示该元素位于两个边框的正中间。如果水平约束条件的偏差更改为 30%,则元素将更接近于左侧边框。如果它更改为 70%,则元素将更接近于右侧边框。垂直约束条件也是如此:偏差用于控制元素与上边框和下边框的间距。

在添加两个相对的水平约束条件(左侧约束条件和右侧约束条件)后,水平滑块将显示在视图检查器中,用于沿水平轴调整元素的偏差。如果您添加了两个相对的垂直约束条件,则将显示用于调整垂直偏差的垂直滑块。

由于 ImageView 的位置是同时使用水平和垂直相对约束条件确定的,因此使用水平和垂直滑块可以调整偏差,如下方动画图形所示:

您还可以点击方向工具来更改方向,然后再调整位置:

更改元素的布局宽度和高度

通过视图检查器内的内部线,您可以更改界面元素相对于约束条件的layout_widthlayout_height值。点击内部线可以循环选择用于垂直和水平约束条件的下列选项:

Fixed:指定元素的宽度/高度。

Match Constraints:允许元素占用所有可用空间以满足约束条件。(请注意,这不同于宽度或高度的match_parent值,此值用于将元素设置为占用父视图的所有可用空间。您不应在 ConstraintLayout 中将match_parent用于任何视图。)在 XML 文件中,值0dp显示在 Match Constraints 的layout_widthlayout_height属性中。

Wrap Content:根据需要扩展元素,以适应其内容。

可以通过更改layout_widthlayout_height值来进行试验。下方的动画图形说明如何使用内部线更改元素的layout_width值:

要使用您学到的技能,请将ImageView的高度调整为 118dp,并将其约束到顶部和两侧,且边距为 0,如下图所示。

提示:您可以直接在layout_height属性中输入118dp

在本练习中,您将添加两个 Button 元素并在这两个元素之间添加一个约束条件,以便将它们放在一起。还将添加两个 TextView 元素,并将其中一个元素约束到另一个元素,以便将它们放在一起,然后使用基线约束条件将它们垂直对齐。

向布局中添加两个 Button 元素

首先,向先前练习中的布局添加两个 Button 元素:

  1. 如果activity_main_start.xml未打开,请将其打开,然后点击Design标签。
  2. 将 Button 从 Palette 拖动到父布局右下角。
  3. 将 Button 约束到父布局的右侧和底部。默认情况下边距设置为 8dp,如下方动画图形所示。

提示:您可以在 Blueprint 视图或 Design 视图中拖动约束条件和对齐元素,如上所示。

将一个元素约束到另一个元素

要在布局内的两个界面元素之间创建约束条件,请点击其中一个元素的约束手柄并将其拖动到另一个元素的约束手柄。

  1. 将另一个 Button 拖动到布局中的任意位置。
  2. 将约束条件从第二个 Button 的右侧拖动到第一个 Button 的左侧,如下方动画图形所示。此约束条件用于在水平方向上将第二个 Button 放置在靠近第一个 Button 的位置,默认边距为 8dp:

  1. 将另一个约束条件从第二个 Button 拖动到布局底部,如下方动画图形所示。Layout Editor 会自动添加 8dp 的边距,并且其结果是,这两个 Button 将垂直对齐。

  1. 使用 Attributes 窗格为每个 Button 添加文本。当您在text属性字段中输入字符s时,系统会显示一个弹出菜单,其中包含项目中的字符串资源,供您进行选择。

您还可以使用 Attributes 窗格向元素分配 ID。在选择某个元素(例如Upload按钮)后,可以将 ID 输入 Attributes 窗格顶部的ID字段中:

使用基线约束条件

通过使用基线约束条件,您可以垂直对齐包含文本的元素(例如 TextView、EditText 或 Button),以便对齐文本基线。利用基线约束条件对齐使用不同文本大小的元素。基线约束条件也可用于对齐不同大小的元素的文本基线。

  1. TextView从 Palette 拖动到布局中。将@string/camera字符串资源分配给其text属性,然后将cameraLabel ID 分配给ID字段。

  1. Plain Text元素从 Palette 拖动到布局中(Plain Text元素是一个EditText视图)。将@string/camera_value字符串资源分配给其text属性,然后将cameraType ID 分配给ID字段。请注意,Plain Text元素使用较大的文本大小,这导致它比 TextView 更宽且更高。
  2. 点击 TextView"Camera"元素,然后将鼠标指针悬停在该元素上。由于该元素包含文本,因此用于基线对齐的ab按钮将显示在该元素下方:

  1. 点击ab按钮以显示文本基线。然后,点击并从 TextView 的基线(以绿色闪烁)拖动到Plain Text元素的基线,如下方动画图形所示:

  1. 现在,可以添加用于缩短两个元素间距的约束条件,然后在布局中将它们移至另一个位置,这两个元素将同时移动并保持对齐:

  1. 您还可以使用基线约束条件对齐 Button 元素。选择Discard按钮,然后将鼠标指针悬停在该按钮上。这将显示用于基线对齐的ab按钮。将Discard按钮的基线拖动到Upload按钮的基线,如下方动画图形所示:

  1. 在添加基线约束条件后,系统将自动移除Discard按钮的底部约束条件。现在,可以更改Upload按钮的边距,而 Discard 按钮将始终与其对齐。选择Upload按钮,然后在 Attributes 窗格中将右边距和下边距更改为 16dp,如下方动画图形所示。

本练习说明了如何通过拖动连接线在元素之间手动创建约束条件的基础知识。在下一部分中,您将学习通过推断创建约束条件。

在本练习中,您将学习如何使用 Pack 工具沿水平和垂直方向扩展某个元素,以及如何使用 Infer Constraints 工具。这两个工具都位于 Layout Editor 顶部的工具栏中。

对于本练习,打开activity_main_inference.xml布局并点击Design标签。请注意以下事项:

Pack 工具

在本练习中,您将为图像说明添加 TextView 并将其扩展以填充可用空间。

  1. 从 Palette 中拖动一个新的 TextView,然后将其放在其他文本元素下方。
  2. 在选中新 TextView 的情况下,点击 Pack 工具中的 Expand Horizontally 工具,水平扩展视图以填充可用空间,如下图所示:

水平扩展文本元素的结果如下:

  1. 在选中 TextView 的情况下,点击 Expand Vertically 工具,垂直扩展此元素以填充可用垂直空间。

垂直扩展文本元素的结果如下:

现在,TextView 将填充布局中的可用空间。

  1. 在选中 TextView 的情况下,在 Attributes 窗格中将其文本设置为@string/singapore_description

Infer Constraints 工具

Infer Constraints 工具用于推断(或确定)与元素的粗略布局相匹配的约束条件。其工作原理是考虑元素的位置和大小。将元素拖动到布局上您需要的位置,然后使用 Infer Constraints 工具自动创建约束条件连接。

点击 Infer Constraints 工具。Layout Editor 会向布局中所有未受约束的元素添加约束条件。生成的布局应如下所示:

提示:您可以点击工具栏中的Device in Editor按钮,以查看不同屏幕上的布局。

布局现在已完成。但是,Layout Editor 可以通过ConstraintLayout提供一些高级功能,包括按比例调整元素大小、使用分界线对齐动态变化的元素以及使用链确定界面元素的位置。下一组练习中将介绍这些功能。

如果至少其中一个元素的尺寸设置为 Match Constraints,您就可以快速地按纵横比调整元素大小。

对于本练习,打开 activity_main_ratio.xml并点击Design标签。将ImageViewPalette拖动到布局中,然后在Resources对话框中选择singapore

选择ImageView并添加约束条件和尺寸,如包含下列标注的下图所示:

  1. 连接到布局底部的底部约束条件,边距为 0。
  2. 连接到布局左侧的侧边约束条件,边距为 0。
  3. 连接到布局顶部的顶部约束条件,边距为 0。
  4. 连接到布局右侧的侧边约束条件,边距为 0。
  5. layout_width属性设置为wrap_content,并且layout_height设置为match_constraint

在您将一个尺寸设置为match_constraint后,Toggle Aspect Ratio Constraint 选项就会显示在检查器视图中方块的左上角。

点击 Toggle Aspect Ratio Constraint 选项。比例输入框将显示在方块的右下角:

要启用纵横比约束条件并将ImageView的纵横比设置为 16:9,请在比例字段中输入16:9

您可以在下方的动画图形中看到完整操作和结果:

通过使用比例,您可以确保设计保持完美效果,同时允许在不同设备屏幕上调整图像大小。

借助分界线,您可以指定基于多个界面元素的约束条件。您可以随时使用分界线,多个元素可以根据用户输入或语言动态更改其大小。

例如,如果用户选择 German,则应用示例会显示德语文本。德语单词可能更长,并且文本可能会与下一个元素重叠。要查看示例,请打开activity_main_barriers.xml并点击Design标签,然后从Language菜单中选择German

下方的动画图形显示在从 English 切换到 German(并返回到 English)时文本元素可能出现的重叠情况:

本练习将向您演示如何向该布局中添加分界线,以确保大小会随语言翻译变化的标签不会与输入字段重叠。

  1. 如果尚未选择German,请从Language菜单中进行选择,以确保应用布局显示为德语。
  2. 在 Blueprint 或 Component Tree 中右键点击ConstraintLayout。您将看到Add Vertical barrierAdd Horizontal barrier选项。

  1. 要为两个 TextView 元素创建垂直线,请选择Add Vertical barrier以添加分界线。您将为两个 TextView 创建垂直线,如下图中的标注 1 所示:

  1. 打开Component Tree以查看您的新分界线。由于分界线在容器启动时进行了刷新,因此您不会在DesignBlueprint视图中发现分界线。您可以在左下方找到Component Tree
  1. 在您的Component Tree同时选中cameraLabelsettingsLabel。在Component Tree中将二者拖动到分界线上。执行此操作时,您将指定分界线应根据以上两个标签的位置调整自身的位置。

  1. Component Tree中选择barrier,然后打开 Attributes 窗格将属性barrierDirection设置为endbarrierDirection是用于控制如何相对于参考视图布置分界线的属性。

在垂直分界线就位后,您可以将元素约束到该分界线的右侧:

  1. 删除从cameraType左侧到cameraLabel("Kamera")右侧的约束条件,如下方动画所示:

  1. 将约束条件从cameraType左侧拖动到分界线:

  1. 现在,您可以使用 Language 菜单从 English 切换到 German 再切换回来,并查看分界线与元素如何对齐,从而不会重叠在一起。

对分界线的约束条件类似于对另一个元素的约束条件。但是,用户看不到分界线,并且分界线不会向应用的视图层次结构中添加级别,这意味着它们不会影响性能。

您已学习如何将单个界面元素居中。在本练习中,您将学习如何使用链同时将多个元素居中。是通过双向位置约束条件相互链接的一组元素。

下图显示了两个元素,它们相互约束,从而创建出一个水平链。

创建链时,您可以将所有元素作为一个组来确定其位置。例如,您可以将所有链接在一起的元素居中,就好像它们是单个元素一样。

对于本练习,打开activity_main_chains.xml并点击Design标签。

  1. 选中两个EditText元素。

  1. 右键点击所选元素,然后从菜单中选择Center Vertically。这将自动创建一个链并生成与父布局的顶部和底部的约束条件。

  1. 检查这两个元素是否采用固定边距。编辑器可能会推断出存在固定的上边距或下边距。如果您发现任何边距,请将它们设置为零。将上边距设置为零后,您将看到元素位于布局中心。

  1. 通过选择cameraType并为其指定下边距8dp,可以在两个EditText元素之间添加边距。
  2. 选择任何一个EditText元素,然后将垂直偏差滑块拖动到20。这会将两个元素向顶部移动,而无需指定固定约束条件。

  1. 点击按钮并选择Switch to Landscape。您将看到,元素会在容器大小发生更改时保持 20% 的偏差。

要了解一些链模式,请点击显示在任何一个EditText元素底部的Cycle Chain Mode按钮

模式为(按顺序显示):

本练习介绍了使用链的基础知识。要了解链的详情,请阅读使用链控制线性组

这些练习说明了如何使用ConstraintLayout视图组创建布局。如需了解 ConstraintLayout 的详情,请参阅使用 ConstraintLayout 构建自适应界面。有关 Layout Editor 的概述,请参阅使用 Layout Editor 构建界面。感谢您试用 ConstraintLayout,希望您喜欢此 Codelab!