Android入门教程:ConstraintLayout约束布局

原文首发自掘金芦苇APP团队,转载到本身小号上再发一遍~java

翻译By Leelion6。关于 ConstraintLayout 的文章其实已经很多了,不过看到这篇文章写的颇有趣,以及在翻译的过程当中,感觉到了不一样文化环境下,写做思惟的不一样。最关键的是,这篇文章的内容很细致,对初学者比较友好,因此翻译过来以供须要的开发者去学习。若是须要进阶的用法欢迎去看郭霖等大神更深刻一些的相关文章。android

在本教程中,你将会使用ConstraintLayout从头开始构建一个登陆界面,从中学习建立Android 视图相关的基础知识。app

做者:Fuad Kamaldom

原文连接:www.raywenderlich.com/9193-constr…编辑器

所需材料及源码下载:koenig-media.raywenderlich.com/uploads/201…分布式

发布日期:2019年1月30日

一款优秀的Android应用程序,须要的不只仅是美观的UI界面,同时还要有良好的性能表现。在绘制页面的时候,你须要把控视图在用户屏幕上的何处出现,以及它出现的方式ide

Android提供了多种布局类型,这些布局中肯定子View的方式都是不一样的。全部布局都来自ViewGroup类。

构建Android UI经常使用的布局有FrameLayout, LinearLayoutRelativeLayout.工具

这些布局易于使用,但当视图结构变得复杂时,它们每一个都有其局限性和一些性能问题:布局

  • FrameLayout 只能经过设置相对于父View的Gravity属性来定位子View
  • LinearLayout 不容许各View相互重叠。大多数状况下,你必须使用多个LinearLayout进行嵌套
  • RelativeLayout 须要的性能较多,由于它老是会作两次布局测量

将包含 `layout_weight`属性的 `LinearLayout` 同 `RelativeLayout`一块儿嵌套使用,将会指数级地增长布局性能成本。这时就须要 `ConstraintLayout` 约束布局来进行拯救了。

在较新版本的Android Studio中,ConstraintLayout已经做为默认布局存在了,而且提供了许多放置对象的方法:能够相对于它们的容器自己进行约束、相对于其余对象约束或者彼此之间进行约束、以及相对于你本身建立的guileline(辅助线)进行约束。这些方法可让你在同一层次中建立大型、复杂、动态和响应式的视图,甚至还能支持动画!

性能

Raze Galactic - 一款星际旅行应用程序

您可使用该应用程序预约行星之间的旅行,计划周末在空间站的度假,并在您抵达后预约月球车。

在本教程中,你将经过从头开始构建星际旅行应用程序的登陆界面UI,以了解ConstraintLayout的基本功能。

在此过程当中,你将学习:

  • 如何添加和删除约束
  • 如何在界面上相对于其余元素动态定位UI元素

注意:本教程假设你熟悉 Android 和 Android Studio 的基础知识。若是你不熟悉 Android 开发,请先查看咱们的 Android入门教程 系列。



入门

打开Android Studio 3.2.1或更高版本,经过从启动界面选择 Start a new Android Studio project 来建立新的Android Studio项目。

在下一个界面中,输入 Raze Galactic 做为 Application name (应用程序名称)。

对于 Company domain (公司域名),你能够输入任意你喜欢的内容。该示例使用 raywenderlich.com

对于 Project location (项目位置),请选择计算机上对你来讲有意义的地址,并确保地址路径中没有空格。你能够点击项目位置字段右侧的省略号 ... 以直接选择计算机上的目录。

最后,确保已选中 Include Kotlin support (添加Kotlin语言支持) 并点击 Next (下一步) 按钮。

译者注:勾选Kotlin语言支持在本文章中并不是必要,后续的内容没有直接使用到Kotilin,因此若是你是纯粹的JAVA语言开发者或者不想使用Kotlin,这里不勾选也彻底OK。

在接下来的界面中,进行Android设备选择,你须要选择 Phone and Tablet (手机和平板电脑),而后选择 API 28: Android 9.0 (Pie) 并点击Next。

译者注:API部分能够按本身习惯选择,不必定非要到Android9.0这么高的版本。

在“Add an Activity to Mobile” (为移动设备添加活动) 界面,选择 Empty Activity (空活动)。在以后你将向这个空活动中添加UI元素,以了解Android中的布局操做。

接下来———你猜对了———点击Next!

在最后一个向导页,Configure Activity(配置活动),保留全部默认配置,须要按Finish便可完成项目配置。



检查ConstraintLayout版本

在开始建立新布局以前,你须要检查ConstraintLayout是否须要版本更新。

你能够在app模块的构建Gradle文件中找到此信息。在Andoird Studio中,打开 app ▸ build.gradle 并查看其中的 dependencies { … }部分。

在各类构建依赖项中,你应该能找到 implementation 'com.android.support.constraint:constraint-layout:x',其中x是项目中ConstraintLayout所使用的版本。

要完成本教程,你须要ConstraintLayout 1.1.3或更高版本。为了确保你拥有最新版本的ConstraintLayout库,请从菜单中选择 Tools ▸ SDK Manager

单击 SDK Tools (SDK工具) 选项卡,在 Support Repository (支持的库) 下查看 ConstraintLayout for Android ,若是显示 installed (已安装),则表示你使用的是最新版本

接下来,选中名为 Show Package Details (显示包详情) 的复选框,以查看项目中包含的库的版本,Gradle文件中的版本号须要与 SDK manager (SDK 管理器) 中安装的版本相匹配。



经过配置 Android Studio 的设计界面以实现高效的约束布局开发

在继续学习本教程以前,请设置Android Studio视图显示方式,以便更轻松地添加和查看约束以及其相关元素。

首先打开 activity_main.xml ,而后单击工具栏中的 Select Design Surface (选择设计界面) 图标,并选择 Design + Blueprint (设计+蓝图)。

如今你在工做时就能看到设计预览界面旁边的蓝图界面了。

蓝图视图能够帮助你更清晰地查看约束和 guidelines (辅助线),而不会被内容或背景分散注意力。

在开发 APP UI 时,你能够在代码视图 (Text tab) 和设计视图 (Design tab) 之间来回切换。

代码视图容许你查看和编辑布局背后的XML,而设计视图对于可视化操做UI元素很是有用。设计视图还提供了 Component Tree (组件树) , 它能让你查看和选择节目中存在的全部UI元素。

当你处于代码视图中,可以看到视觉预览和蓝图是颇有用的。这样,当你在预览界面中选择任何元素时,XML中相应的代码块将变成高亮显示。

若是你在代码视图中没有看到预览界面,请单击右侧的 Preview (预览) 选项卡。



从头开始建立新的ConstraintLayout

对于接下来的这一步,请打开 activity_main.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"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity">

  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>
复制代码

请注意,此布局的默认根元素是android.support.constraint.ConstraintLayout。另外,带有 “Hello World!” 文本的TextView元素已经有了一些约束属性,例如app:layout_constraintBottom_toBottomOf="parent",它的做用是将此视图的底部约束到其父容器的底部。

在相对其父容器顶部、底部、左侧还有右侧都约束后,包含 “Hello World!”的 TextView便处于了屏幕的中心。

切换到设计视图并将鼠标光标移到包含 “Hello World!” 的TextView上, 能够看到有四条波浪线将TextView链接到其父容器上,这些线表示TextView已经应用了约束规则。

若是没有出现这些线,请单击TextView,而后它们就会出现。若是已选中 Show Constraints (显示约束) 视图选项,则无需使用鼠标光标悬停或选择任何视图,就能够看到全部约束。



向APP中添加图像

对于下一步,你将须要在本教程开头的应用程序屏幕截图中看到的火箭图像。使用教程开头的“ 下载材质”按钮下载本教程的材料,或者点此下载。你能够在 RazeGalactic-starter 文件夹中找到 track_icon.png

获取 track_icon.png 并将其添加到项目的 drawable 文件夹中。您能够经过在Mac上使用 command-C 或在Windows上使用 control-C 进行复制,而后右键单击Android项目中的 drawable 文件夹并使用Mac上的 command-V 或Windows上的 control-V 粘贴图像到项目中。

您能够将UI元素从 Palette (调色板) 拖放到设计界面中。若是没有看到 Palette ,请单击垂直 Palette 选项卡图标。

删除“Hello World!”,而后将如下UI元素拖到 Palette 中的视图中:

  • 1个 ImageView, 提示选择图像时选择火箭图像。

  • 3个 Button

  • 3个 TextView

更改UI元素的文本并将其拖动到屏幕周围,以使它们看起来像本教程开头的最终布局预览。不要过度在乎视图的尺寸、间距或对齐的精度。

接下来,你须要添加android:textAppearance="@style/TextAppearance.AppCompat.Headline"Raze Galactic TextView以得到合适的样式。

请注意,当你在屏幕上拖动视图时,这些小对齐线是能帮助到你的,这些线条能够很容易地将视图们相互排列。



测试视图放置的位置

如今,构建并运行你的应用程序。

天了噜!视图没有按你在设计视图中分配好的位置排列!一切都在屏幕的左上角蜷缩着,这是肿么回事?

嗯..好吧,Android获得如何放置UI元素的这部分信息,由于你添加的视图没有任何已定义的约束。因此你须要解决这个问题。

回到Android Studio,能够看到 Component Tree (组件树) 中的每一个新视图如今都有一系列错误。要查看错误的完整文本,请单击Component Tree (组件树)中的红色感叹号。

错误以下:

此视图不受约束。它仅包含在刚添加时的位置,因此它会在运行时放置于(0,0)的位置,除非你添加约束。
切换回代码视图以检查布局XML的源代码。请注意,任何视图的源代码都有一些带tools前缀的属性,例如:

<ImageView
    android:id="@+id/imageView"
    android:layout_width="46dp"
    android:layout_height="46dp"
    app:srcCompat="@drawable/track_icon"
    tools:layout_editor_absoluteX="16dp"
    tools:layout_editor_absoluteY="16dp" />
复制代码

布局编辑器容许你将小部件放在画布上的任何位置,并使用tools前缀属性记录当前位置。这些属性在实际运行时并不会被应用,请记住这一点。

译者补充: tools前缀的属性都是服务于布局编辑器中的,只在XML的预览视图中起做用,实际运行时是没有用的。

开始了解布局编辑工具栏

切换回布局的设计视图,你能够在布局预览得上方看到一堆小控件。若是将鼠标悬停在每一个控件上,能够阅读该控件的简要说明。

自动链接

单击工具栏中的磁铁图标以启用 Autoconnect (自动链接) ,将任何视图拖动到父视图角落附近的区域,此时Android Studio将自动为你建立新约束。

请注意,这仅适用于在UI元素及其父视图之间建立约束,而不是在UI元素之间建立约束,所以 Autoconnect 的用处很是有限。大多数状况下,你仍是关闭 Autoconnect 吧。

自动链接(推测约束)

接下来,单击 Infer Constraints (推测约束) 按钮,Android Studio会自动添加布局中缺乏的约束。

再次构建并运行您的应用,会发现如今这些组件不在角落,而是出如今你放置它们的位置了。

这是添加约束的最简单方法,但也多是最很差的。由于Android Studio布局的意图每每和你实际的意图不一样。

使用自动链接在特定大小的状况下布局多是正常的,但在不一样的屏幕大小或屏幕方向上,可能就不会像你所但愿的样子布局了。



清除全部约束

若是约束混乱,你能够清除全部约束并从头开始从新添加约束。具体方法是,点击 Clear All Constraints (清楚全部约束) 按钮清除当前页面全部约束。



添加和删除个别约束

Android提供了多种选项,能够将UI元素限制在屏幕的不一样部分,让你灵活地设计布局。

在本教程的这一部分中,你将学习如何将对象约束到其容器,删除单个约束以及将对象约束到另外一个对象以达到动态布局的效果。

将对象约束到其容器

请注意,当你单击ImageView时,它会突出显示,而且视图的顶部,底部,左侧和右侧会出现小圆圈。这些圆圈是你的约束锚点。

当你将鼠标悬停在其中一个约束锚点上时,它将闪烁绿色。Android Studio会提示你建立约束链接。

单击元素左侧的圆圈并将其拖动到左侧。在拖动时,将出现带箭头的线条,在UI元素的左侧和要将其链接到的元素之间建立约束。

将圆拖动到视图的左侧,并将圆圈ImageView的 左侧约束到父视图的左部。对圆圈ImageView的顶部重复此操做,将其约束到父视图顶部。您如今已将ImageView的约束限制在视图的左上角。

将图像向下拖动一点,Android Studio将在顶部建立一个边距。经过在代码视图中编辑XML代码或在设计视图的 Attributes (属性) 检查器中对其进行编辑,将顶部边距设置为30dp。

接下来,选择 Raze Galactic TextView, 将左约束锚点拖动到父视图的左侧,将右约束锚点拖动到父视图的右侧。经过将此UI元素约束到左侧和右侧,Android明白你是想将其达到居中的效果。



删除个别约束

接下来,将鼠标光标放在已设置约束的约束锚点之一上,表示箭头的圆圈如今应该闪烁红色,约束也会以红色突出显示。

单击锚点就会删除约束。如今先不要单击,并将约束锚点保留在原位,但若是之后须要删除约束,请记住该操做。

如今你知道如何将UI元素约束到其父容器的边框,接下来到了学习如何将UI元素相互约束的时候了。

将对象彼此之间进行约束

在本教程的这一步中,你将实现 Raze Galactic TextView始终与火箭图像对齐。

要作到这一点,你须要把 Raze Galactic TextView的顶部锚点约束到ImageView的顶部锚点,同时将TextView底部锚点固定到ImageView的底部锚点。两个视图便会垂直对齐。

如今,若是你按住火箭上下拖动,你将看到 Raze Galactic 随着图像上下移动。

稍后,你将看到如何使用对齐菜单建立这样的对齐。可是,该方法并不老是天衣无缝的,因此知道如何手动完成它也是一件好事。

切换到Android Studio中的代码视图,并检查刚才添加约束的视图的代码:

<ImageView
    android:id="@+id/imageView2"
    android:layout_width="46dp"
    android:layout_height="46dp"
    android:layout_marginStart="16dp"
    android:layout_marginTop="30dp"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:srcCompat="@drawable/track_icon"/>

  <TextView
    android:id="@+id/textView2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:text="Raze Galactic"
    android:textAppearance="@style/TextAppearance.AppCompat.Headline"
    app:layout_constraintBottom_toBottomOf="@+id/imageView2"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="@+id/imageView2"/>

复制代码

如今你已经添加了一些约束,带有tools前缀的属性已经消失,由于Android Studio如今再也不须要仅设计时生效的这些属性了。

你添加的每一个约束都会在代码中提现,好比app:layout_constraintTop_toTopOf="parent",表明该元素的顶部约束到了父布局的顶部。

你能够看到Android Studio为你设置了一些边距,也许你并无想过去添加。这些边距可能看起来像android:layout_marginStart="16dp"

继续往下看,在 Raze Galactic TextView中 删除边距属性后切换回设计视图,如今你会发现, Raze Galactic TextView应该与火箭图像对齐了。

这两个视图不会再有错误出现了,由于已经知足了Android Studio放置这两个UI元素所须要的信息量下限。

注意:你仍可能会看到有关使用硬编码字符串或丢失的警告contentDescription。不过你如今如今能够忽略这些。

如今,你应该将 ** Login** (登陆)按钮与 Sign Up (注册) 按钮对齐,就像将 Raze Galactic TextView与火箭图像对齐同样。为此,你将须要设置三个约束:

“登陆”按钮的顶部锚点位于“注册”按钮的顶部。 “登陆”按钮的底部锚点位于“注册”按钮的底部。 “登陆”按钮的左侧锚点位于“注册”按钮的右部,并设置从左起30dp的起始边距以在它们之间留出一些空间。



应用对齐约束

选择 Raze Galactic TextView并单击右侧锚点以删除这些约束。而后,在TextView仍然选中时,单击工具栏中的 Align (对齐)工具,而后在选择 Horizontally in Parent (水平布局)。

这会自动将Raze Galactic TextView相对父容器进行居中布局。这与你在手动添加约束时以前实现的效果相同。

事实上,若是你切换到代码视图并仔细检查Raze Galactic TextView,你会注意到Android Studio添加了如下约束属性:

app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
复制代码

这时你可能问了,Android Studio中自动添加的layout_constraintHorizontal_bias是什么?

Constraint Bias(约束误差)

当视图在水平或垂直方向上受到约束时,不管是父视图仍是其余视图,默认状况下它具备0.5或50%的约束误差。换句话说,视图保持在它受约束的两条边之间的中心。

约束误差范围从0.0(0%)到1.0(100%),水平约束误差从左到右增加,而垂直约束误差从上到下增加。约束误差对于为不一样的屏幕尺寸动态定位视图颇有用。

要更轻松地了解约束误差的工做原理,请切换回设计视图。选中 Raze Galactic TextView,在右侧查看 view inspector (视图查看器) 以及各类 Attributes(属性)。

视图查看器左侧的垂直滑块控制垂直约束误差,底部的垂直滑块控制水平约束误差。拖动每一个滑块以查看约束误差的工做原理:

在继续下一步以前,将水平和垂直约束的误差重置为50%。



对齐左边缘并垂直分布

接下来,同时选择全部TextViewGoogle Sign-In(从谷歌登陆) 和 Sign-Up (注册) 按钮。你能够按住Shift键单击每一个UI元素依次所有选中它们。而后,从工具栏中单击 Align (对齐) 并选择 Left Edges (左边缘) 。

这是应用左对齐后的布局:

你注意到这里有什么问题了吗? Raze Galactic TextView的水平约束变不见了。

左边缘将视图与所选择的最左侧视图对齐,它实际上作的是按降序从一个视图建立左约束依赖关系,以最底部的视图充当锚点。

所以,要使 Left Edges (左边缘)命令起做用,它必须删除其他所选视图的现有水平约束。

要反转约束依赖关系顺序,请再次应用 Left Edges (左边缘)命令。您能够看到约束箭头如今指向上方。

如今,使用与上一步骤中选择的相同UI元素,单击 Pack (包) 菜单并选择 Distribute Vertically (垂直分布) 。

垂直分布后,你的屏幕将以下所示:

一样,你可能已经注意到与上述相似的问题:链接火箭图标底部和 Raze Galactic TextView的约束属性已经消失。

约束依赖性按降序排列,就像在第一个 Left Edges (左边缘) 命令以后同样。不幸的是,没有简单的方法来解决这个问题,所以您必须手动建立垂直分布式约束。

本教程将介绍如何在下一部分中执行此操做,所以请继续并撤消 Distribute Vertically (垂直分布) 命令。

注意:AlignPack 命令可能没法正常工做。它们可能会删除现有的约束,而且可能不会移动某些受约束的视图。在应用这些命令以前和以后,请务必检查受影响视图的约束。



使用默认边距

要建立垂直分布式约束,只需链接具备相同边距的约束便可。快速完成此操做的一个技巧是使用 Default Margin (默认边距) 工具。

如今,单击 Default Margin (默认边距) 按钮并设置值为60dp,而后将Google登陆按钮的顶部约束链接到 Raze Galactic TextView的底部。你会发现Google登陆按钮会自动变换位置,在它与 Raze Galactic TextView之间留出60dp的间距。 魔法 :]

建立其他的垂直约束,如上面的GIF所示。最后,将到 Raze Galactic TextView的左侧约束到火箭图标的右侧,边距为30dp。

检查组件树以查看是否存在其余错误。若是没有错误,恭喜!

构建并运行你的应用程序,如今全部内容应该在模拟器中以适当的布局显示了。



接下来作什么?

你可使用本教程顶部的下载材质按钮下载此项目的最终版本。

ConstraintLayout 在布局编辑器中构建UI 可能会使人沮丧,由于某些工具不够智能。可是,若是若是你知道如何正确的去使用,则能够节省大量时间。

本教程中未说起其余布局编辑器工具,你能够去使用它们来了解它们的工做原理。看看谷歌ConstraintLayout的文档上,以了解更多信息。

有关更复杂的ConstraintLayout示例,请参阅咱们的后续文章ConstraintLayout Android教程:复杂布局

要查看更多ConstraintLayout的示例,请查看咱们的 Android Apprentice 一书,该书使用ConstraintLayout做为全部页面的布局。

你如今已经掌握了ConstraintLayout基本的概念,要了解更多高级功能并得到处理复杂布局的提示,请继续关注咱们即将推出的构建复杂布局的教程ConstraintLayout Android教程:复杂布局,你将在其中为 Raze Galactic 旅行应用程序构建更复杂的约束视图,而后为其制做动画!

若是你有任何问题或意见,欢迎在下方留言讨论~

相关文章
相关标签/搜索