使用ConstraintLayout(约束布局)构建响应式UI
使用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, 冰冻鱼. 请尊重作者劳动成果,复制转载保留本站链接!应用开发笔记
使用ConstraintLayout(约束布局)构建响应式UI的更多相关文章
- Android响应式UI教程
原文:Responsive UI Tutorial for Android 作者:James Nocentini 译者:kmyhy 2017/5/4 更新说明: 由 James Nocentini 更 ...
- Skeljs – 用于构建响应式网站的前端开发框架
skelJS 是一个轻量级的前端框架,用于构建响应式站点和应用程序.让设计人员和开发人员可能够使用四个强大的组件:CSS 网格系统,响应式处理程序,CSS 的快捷方式和插件系统. 您可能感兴趣的相关文 ...
- 使用 Responsive Elements 快速构建响应式网站
Responsive Elements 可以使任何元素来适应和应对他们所占据的区域.这是一个轻量的 JavaScript 库,你可以轻松嵌入到你的项目.元素会更具自己的宽度,自动响应和适应空间的增加或 ...
- html响应式布局,css响应式布局,响应式布局入门
html响应式布局,css响应式布局,响应式布局入门 >>>>>>>>>>>>>>>>>>& ...
- FLEX 网格布局及响应式处理
上一篇文章用Flex实现BorderLayout,这一章我们来实现常用的网格布局和响应式处理. 首先我们定义HTML结构,主Box为grid,每项为grid-cell,下面就是我们HTML代码结构. ...
- 实战SpringCloud响应式微服务系列教程(第八章)构建响应式RESTful服务
本文为实战SpringCloud响应式微服务系列教程第八章,讲解构建响应式RESTful服务.建议没有之前基础的童鞋,先看之前的章节,章节目录放在文末. 1.使用springboot2.1.4构建RE ...
- 实战SpringCloud响应式微服务系列教程(第九章)使用Spring WebFlux构建响应式RESTful服务
本文为实战SpringCloud响应式微服务系列教程第九章,讲解使用Spring WebFlux构建响应式RESTful服务.建议没有之前基础的童鞋,先看之前的章节,章节目录放在文末. 从本节开始我们 ...
- 前端开发工程师 - 04.页面架构 - CSS Reset & 布局解决方案 & 响应式 & 页面优化 &规范与模块化
04.页面架构 第1章--CSS Reset 第2章--布局解决方案 居中布局 课堂交流区 水平列表的底部对齐 如图所示,一个水平排列的列表,每项高度都未知,但要求底部对齐,有哪些方法可以解决呢? & ...
- Android Material Design控件使用(一)——ConstraintLayout 约束布局
参考文章: 约束布局ConstraintLayout看这一篇就够了 ConstraintLayout - 属性篇 介绍 Android ConstraintLayout是谷歌推出替代PrecentLa ...
随机推荐
- 管理Linux软件——aptitude
https://help.ubuntu.com/lts/serverguide/aptitude.html.en
- K8S 1.12大特性最快最深度解析:Kubernetes CSI Snapshot(上)
背景 许多存储系统提供了创建存储卷“快照”(snapshot)的能力,以防止数据丢失.快照可以替代传统的备份系统来备份和还原主要数据和关键数据.快照能够快速备份数据(例如,创建GCE PD快照仅需 ...
- 循环双端链表(python)
# -*- coding: utf-8 -*- class Node(object): __slots__ = ('value', 'prev', 'next') # save memory def ...
- 匿名函数、sorted()、filter()、map()、递归
一.匿名函数 1.lambda 匿名函数 方法 lambda 参数:返回值 (函数名统一叫lambda) def func(n): return n**2 print(func(3)) #这是一个普通 ...
- 使用python控制nginx禁封ip
python控制nginx禁封ip nginx中的access.log最近有大量的用户访问,怎么样屏蔽掉在一定时间段内访问次数多的ip呢? 测试准备: 两个tomcat,一个nginx做均衡负载,服务 ...
- spring中少用的注解@primary解析
这次看下spring中少见的注解@primary注解,例子 @Component public class MetalSinger implements Singer{ @Override publi ...
- Maven Module和Maven Project的区别
1.maven project和module相当于父子关系.2.当新建的项目中不存在父子关系时使用project.3.当项目中存在父子关系时用project做父工程,module做子工程,module ...
- Qt--解析Json
一.QT5 Json简介 QT4中使用第三方库QJson解析JSON文件. QT5新增加了处理JSON的类,类均以QJson开头,包含在QtCore模块中.QT5新增加六个相关类: QJsonArra ...
- Linux Soft-RoCE implementation (zz)
Linux Soft-RoCE implementation 首页分类标签留言关于订阅2017-11-08 | 分类 Network | 标签 RDMA RoCE Linux-RDMA 内核在4 ...
- 视觉SLAM十四讲(三)——三维空间刚体运动(下)
理论部分请看 :三维空间刚体运动 一.Eigen的使用 首先安装 Eigen: sudo apt-get install libeigen3-dev 一般都安装在 /usr/include/eigen ...