使用ConstraintLayout(约束布局)构建响应式UI
ConstraintLayout
(约束布局)是Google IO 2016推出的Android新布局方式。
以下内容翻自官方文档。
ConstraintLayout
允许您使用扁平的层级(不用嵌套View Group)创建大型复杂的布局。与 RelativeLayout
类似,它通过相邻的view和父layout的相对关系来确定位置,但比 RelativeLayout
更加灵活,更容易通过Android Studio的布局编辑器实现想要的效果。
ConstraintLayout
的所有功能都可以直接通过 Layout Editor
可视化工具实现,因为布局API和Layout Editor互相做了特别优化。所以您 只需要拖放布不必编写一行代码构建ConstraintLayout布局。
图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的左右边缘水平对齐,但出现在屏幕的最顶部,因为它没有垂直约束.
图2: TextView B缺少垂直约束
图3:TextView B现在相对ImageView水平垂直约束
尽管缺少约束不会导致编译错误,Layout Editor还是会在工具栏上将缺少约束显示为错误。
查看错误和其他警告,点击错误数字图标。为了帮您避免缺少约束,Layout Editor可以使用Autoconnect和infer constraints 特性,帮您自动添加约束。
为您的项目添加ConstraintLayout
要在项目中使用 ConstraintLayout
,跟随以下步骤:
1.确保您有最新的约束布局库:
– 点击 Tools
> Android
> SDK Manager
.
– 点击 SDK Tools
选项卡
– 展开 Support Repository
,勾选 ConstraintLayout for Android
和 Solver 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
图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,点击约束把手
当您添加了相反的约束时,约束线会变成弯弯曲曲的弹簧状。
这个效果当view的size设置成 fixed
或 wrap_content
时最明显,它会让view展示在约束的中间,如果您希望view扩展它的尺寸到约束上,,或者如果您 想保持当前大小,但是移动view,以便它不居中,可以
有很多方法可以限制一个视图,但是下面的约束类型提供的基本构建块。
父级约束
连接view的一边到相应的layout边缘,在图5中,view的左边缘连到了父级的左边缘。
图5 相对父级的水平约束
位置约束
为两个view水平或垂直方向定义外观规则。图6中,一个 Button
被约束在一个 ImageView
下面,间隔24dp
图6 垂直位置约束
对齐约束
一个view的边缘与另一个view的同一边缘对齐
图7中, Button
的左边缘与ImageView的左边缘对齐
您可以通过向内拖动view调整对齐(增加margin,不支持向外拖,即margin不能为负值)
图7 水平对齐约束
图8 水平对齐约束 offset
基线对齐约束
对齐一个view的文本基线到另一个view的文本基线。
图9中, TextView
的第一行与 Button
的文本对齐
创建一个基线约束,您可以选中view,点击B,基线就会显示,鼠标拖到另一个view的基线上即可(原文描述有点不一样,可能是Android Studio老版本)
与引导线约束
您可以添加水平或垂直的引导线,基于它创建约束。您可以在layout内部用dp单位或者百分比放置引导线,相对layout边缘。
创建引导线:点击工具栏上的 Guidelines
图标,选择 Add Vertical Guideline
或 Add 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。
图10 属性窗口,包含视图尺寸(1),边距(2),约束偏移(3)
灰色的区域展示了选中的view,距形内的符号展示了宽高设置:
- Wrap Content View会根据内容的需要自动展开
- Any Size View会自动展开来匹配约束。实际值是0dp,因为view没有期望的尺寸,但它会为匹配约束重置大小。然而,如果给定的尺寸只有一个约束,视图会扩展以适应内容。对此的另一种理解是
match constraints
(而不是match_parent
),因为它在计算约束和边距的限制后,尽可能多地展开视图。 - Fixed 您在编辑器里通过调整view大小,在下面的文本框里指定了尺寸
要在这几种模式间切换,在上面的图形上单击。
==注意:您不应该在ConstraintLayout上使用 match_parent
,用 Any Size
0dp 代替==
调整约束偏移
当您给一个view的两边都添加了约束(并且view的尺寸是都是fixed或者wrap content),默认情况下,view会在两个锚点间居中。当一个view居中时,偏移是50%.您可以通过拖动属性窗口中的偏移滑动条或拖动view来调整。
如果您想要view扩展它的尺寸到匹配约束,
调整view间距
确保您的view间隔均匀,点击工具栏上的Margin 8
,为您添加的每个view选择默认的间距。这个按钮会展示您当前的默认间距设置。任何对默认间距的修改,仅对修改后新增的约束生效。
您可以通过属性窗口单独修改每个view的间距,(在图10中,边距被设为16dp).
工具中提供的所有边距都是8的倍数,以帮助您的view符合Material Design的 8dp square grid recommendations
© 2017, 冰冻鱼. 请尊重作者劳动成果,复制转载保留本站链接!应用开发笔记