使用ConstraintLayout(约束布局)构建响应式UI

ConstraintLayout(约束布局)是Google IO 2016推出的Android新布局方式。

以下内容翻自官方文档。

ConstraintLayout允许您使用扁平的层级(不用嵌套View Group)创建大型复杂的布局。与RelativeLayout类似,它通过相邻的view和父layout的相对关系来确定位置,但比RelativeLayout更加灵活,更容易通过Android Studio的布局编辑器实现想要的效果。

ConstraintLayout的所有功能都可以直接通过Layout Editor可视化工具实现,因为布局API和Layout Editor互相做了特别优化。所以您 只需要拖放布不必编写一行代码构建ConstraintLayout布局。

image
图1. Layout Editor编辑ConstraintLayout

ConstraintLayout的Api库兼容 Android 2.3 (API level 9)或更高版本,新的Layout Editor需要Android Studio 2.2或更高版本

本文提供了在Android Studio中使用ContraintLayout构建布局的向导,如果您对Layout Editor更兴趣,参见 Build a UI with Layout Editor.

约束概览

ConstraintLayout中定义一个view的位置,您必须为这个view添加至少两条约束。每个约束代表与另一个view、父layout,或不可见的向导线的连系或对齐。每个约束沿着水平或垂直坐标定义了view的位置,所以每个view必须在每个轴上有一个最小约束,但通常需要多个。

当您把一个view拖进Layout Editor时,即便没有约束,它也会留在你释放时的位置。然而,这仅仅是让您更容易编辑,如果一个view没有约束,当您在设备中运行时,它始终会在左上角显示。

在图2中,布局在编辑器中看起来很好,但TextView B没有垂直约束。当这个布局在设备中运行时,TextView B会与ImageView的左右边缘水平对齐,但出现在屏幕的最顶部,因为它没有垂直约束.

image
图2: TextView B缺少垂直约束

image
图3:TextView B现在相对ImageView水平垂直约束

尽管缺少约束不会导致编译错误,Layout Editor还是会在工具栏上将缺少约束显示为错误。
image 查看错误和其他警告,点击错误数字图标。为了帮您避免缺少约束,Layout Editor可以使用Autoconnect和infer constraints 特性,帮您自动添加约束。

为您的项目添加ConstraintLayout

要在项目中使用ConstraintLayout,跟随以下步骤:
1.确保您有最新的约束布局库:
– 点击 Tools > Android > SDK Manager.
– 点击 SDK Tools 选项卡
– 展开Support Repository,勾选ConstraintLayout for AndroidSolver for ConstraintLayout,勾选Show Package Details,记住您下载的版本(下面会用到)
– 点击 OK
– 在module级别(默认app)的build.gradle里添加ConstraintLayout库依赖

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

您下载的版本可能更高,所以确保版本号与下载的匹配.

  • 在工具栏或同步通知里,点击Sync Project with Gradle Files

现在,您已经准备好使用ConstraintLayout构建布局了

转换布局

转换现有布局到ConstraintLayout,跟随以下步骤:
1. 在Android Studio中打开layout,在编辑器的底部,点击Design标签,
2. 在Component Tree窗口,右击layout,点击 Convert layout to ConstraintLayout
image
图4:转换布局菜单

创建新布局

创建一个新的ConstraintLayut,跟随以下步骤:
1. 在Project窗口任意处点击,选择File > New > XML > Layout XML.
2. 输入layout文件名,android.support.constraint.ConstraintLayout作为Root Tag
3. 点击Finish

添加约束

Palette拖动一个view到编辑器里开始。当您添加一个view到ConstraintLayout里时,它展示成一个包围的盒子,四角带方形大小调整把手,四边的中间带圆形约束把手。

点击View选中它,点击并拖住一个约束把手,拖动到可用的锚点上(另一个view、layout、引导线的边缘),当您释放时,约束就生成了,两个view间带一个默认的margin值

演示视频

创建约束时,记住以下准则:

  • 每个view至少有两个约束,一个水平,一个垂直
  • 同一平面上,您可以只在一个约束把手和一个锚点间创建约束。所以一个view的垂直平面(左右边) 可以只被另一个垂直平面约束;基线可以只被其他基线约束
  • 每个约束把手只能创建一个约束,但是同一个锚点上可以创建多个约束(不同的view)

如果要删除约束,选中view,点击约束把手

当您添加了相反的约束时,约束线会变成弯弯曲曲的弹簧状。
image
这个效果当view的size设置成fixedwrap_content时最明显,它会让view展示在约束的中间,如果您希望view扩展它的尺寸到约束上, 把尺寸切到any size,或者如果您 想保持当前大小,但是移动view,以便它不居中,可以
调整约束偏移

有很多方法可以限制一个视图,但是下面的约束类型提供的基本构建块。

父级约束

连接view的一边到相应的layout边缘,在图5中,view的左边缘连到了父级的左边缘。
image

图5 相对父级的水平约束

位置约束

为两个view水平或垂直方向定义外观规则。图6中,一个Button被约束在一个ImageView下面,间隔24dp
image

图6 垂直位置约束

对齐约束

一个view的边缘与另一个view的同一边缘对齐

图7中,Button的左边缘与ImageView的左边缘对齐

您可以通过向内拖动view调整对齐(增加margin,不支持向外拖,即margin不能为负值)

image

图7 水平对齐约束

image

图8 水平对齐约束 offset

基线对齐约束

对齐一个view的文本基线到另一个view的文本基线。

图9中,TextView的第一行与Button的文本对齐

创建一个基线约束,您可以选中view,点击B,基线就会显示,鼠标拖到另一个view的基线上即可(原文描述有点不一样,可能是Android Studio老版本)

image

与引导线约束

您可以添加水平或垂直的引导线,基于它创建约束。您可以在layout内部用dp单位或者百分比放置引导线,相对layout边缘。

创建引导线:点击工具栏上的Guidelines图标,选择Add Vertical GuidelineAdd Horizontal Guideline

点击引导线顶部的小圆点,切换百分比以及相对边缘(上下,或左右)

引导线对用户不可见

使用Autoconnect和Infer Constraints

Autoconnect会为您添加到layout里的每一个view创建两个或更多约束。Autoconnect默认关闭,您可以点击Layout Editor工具栏上的Turn on Autoconnect图标开启。

当开启后,Autoconnect会在您添加view后创建约束,它不会为已经存在的view(开启前添加)创建约束。如果您在约束创建后拖动view,约束不会改变(虽然margin会),所以如果您要大幅度改变view位置,您必须删除约束。

作为另一种选择,您也可以点击Infer Constraints来为layout里的所有view创建约束.

Infer Constraints(推断约束)是一次性的动作,它通过扫描整个layout来推断所有view的最有效设置,所以它可能会为两个很远的view创建约束。Autoconnect只与最近的元素创建约束。这两种情况下,你都可以通过点击约束把手删除约束,创建新的约束.

调整视图大小

您可以使用view每个角上的把手调整大小,但这么做会硬编码(Hard codes)宽和高,这是您应该避免的,因为硬编码无法适配不同的内容的屏幕尺寸。要选择不同的动态尺寸模式,或定义指定大小,点击view,打开编辑器右边的属性窗口,在窗口的顶部是视图查看器,如图10。

image

图10 属性窗口,包含视图尺寸(1),边距(2),约束偏移(3)

灰色的区域展示了选中的view,距形内的符号展示了宽高设置:

  • image Wrap Content View会根据内容的需要自动展开
  • image Any Size View会自动展开来匹配约束。实际值是0dp,因为view没有期望的尺寸,但它会为匹配约束重置大小。然而,如果给定的尺寸只有一个约束,视图会扩展以适应内容。对此的另一种理解是match constraints(而不是match_parent),因为它在计算约束和边距的限制后,尽可能多地展开视图。
  • image Fixed 您在编辑器里通过调整view大小,在下面的文本框里指定了尺寸

要在这几种模式间切换,在上面的图形上单击。

==注意:您不应该在ConstraintLayout上使用match_parent,用Any Size 0dp 代替==

调整约束偏移

当您给一个view的两边都添加了约束(并且view的尺寸是都是fixed或者wrap content),默认情况下,view会在两个锚点间居中。当一个view居中时,偏移是50%.您可以通过拖动属性窗口中的偏移滑动条或拖动view来调整。

如果您想要view扩展它的尺寸到匹配约束, 把尺寸切到any size

调整view间距

确保您的view间隔均匀,点击工具栏上的Margin 8,为您添加的每个view选择默认的间距。这个按钮会展示您当前的默认间距设置。任何对默认间距的修改,仅对修改后新增的约束生效。

image

您可以通过属性窗口单独修改每个view的间距,(在图10中,边距被设为16dp).

工具中提供的所有边距都是8的倍数,以帮助您的view符合Material Design的8dp square grid recommendations

© 2017, 冰冻鱼. 请尊重作者劳动成果,复制转载保留本站链接! 应用开发笔记