介绍

一个 ConstraintLayout 是一个 ViewGroup 允许您以灵活的方式定位和调整小部件的方法。

注意: ConstraintLayout 作为支持库提供,您可以在API级别9(Gingerbread)开始的Android系统上使用。

约束布局

您目前可以使用各种类型的约束:

请注意,您不能在约束中具有循环依赖关系。

另请参阅 ConstraintLayout.LayoutParams 布局属性

开发指南 Developer Guide

相对定位

相对定位是在ConstraintLayout中创建布局的基本构建块之一。这些约束允许您将给定的小部件相对于另一个小部件进行定位。您可以在水平和垂直轴上约束小部件:

  • 水平轴:左,右,起点和终点
  • 垂直轴:顶部,底部和文本基线

一般概念是将窗口小部件的给定侧约束到任何其他窗口小部件的另一侧。

例如,为了将按钮B定位在按钮A的右侧(图1):

你需要这样做:

<Button android:id="@+id/buttonA" ... />
<Button android:id="@+id/buttonB" ...
app:layout_constraintLeft_toRightOf="@+id/buttonA" />

这告诉系统我们希望按钮B的左侧被约束到按钮A的右侧。这样的位置约束意味着系统将尝试让双方共享相同的位置。

图2 - 相对定位约束

以下是可用约束的列表(图2):

  • layout_constraintLeft_toLeftOf
  • layout_constraintLeft_toRightOf
  • layout_constraintRight_toLeftOf
  • layout_constraintRight_toRightOf
  • layout_constraintTop_toTopOf
  • layout_constraintTop_toBottomOf
  • layout_constraintBottom_toTopOf
  • layout_constraintBottom_toBottomOf
  • layout_constraintBaseline_toBaselineOf
  • layout_constraintStart_toEndOf
  • layout_constraintStart_toStartOf
  • layout_constraintEnd_toStartOf
  • layout_constraintEnd_toEndOf

它们都引用id另一个小部件,或者parent引用父容器,即ConstraintLayout:

<Button android:id="@+id/buttonB" ...
app:layout_constraintLeft_toLeftOf="parent" />

边距

图3 - 相对定位边距

如果设置了边距,则它们将应用于相应的约束(如果存在)(图3),将边距强制为目标和源边之间的空间。通常的布局边距属性可用于此效果:

  • android:layout_marginStart
  • android:layout_marginEnd
  • android:layout_marginLeft
  • android:layout_marginTop
  • android:layout_marginRight
  • android:layout_marginBottom

请注意,边距只能是正数或等于0,并且是一个尺寸(例如 0dp,它是尺寸,有单位)。

连接到GONE小部件时的边距

当位置约束目标的可见性为View.GONE,您还可以使用以下属性指示要使用的不同边距值:

  • layout_goneMarginStart
  • layout_goneMarginEnd
  • layout_goneMarginLeft
  • layout_goneMarginTop
  • layout_goneMarginRight
  • layout_goneMarginBottom

居中定位和偏移

一个有用的方面ConstraintLayout是它如何处理“不可能”的约束。例如,如果我们有类似的东西:

<android.support.constraint.ConstraintLayout ...>
<Button android:id="@+id/button" ...
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent/>
</>

除非ConstraintLayout恰好具有Button与之完全相同的大小,否则两个约束不能同时满足(双方都不能成为我们想要它们的地方)。

图4 - 定心定位

在这种情况下发生的事情是,约束的作用就像是相反的力量将小部件平分开(图4); 这样小部件最终将在父容器中居中。这同样适用于垂直约束。

偏压

遇到这种相反的约束时的默认设置是使窗口小部件居中; 但是您可以使用偏差属性调整定位以支持一侧而不是另一侧:

  • layout_constraintHorizontal_bias
  • layout_constraintVertical_bias

图5 - 偏置定心定位

例如,以下将使左侧具有30%的偏差而不是默认的50%,这样左侧将更短,小部件更倾向于左侧(图5):

<android.support.constraint.ConstraintLayout ...>
<Button android:id="@+id/button" ...
app:layout_constraintHorizontal_bias="0.3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent/>
</>

使用偏差,您可以制作更好地适应屏幕尺寸变化的用户界面。

循环定位(1.1中增加)

您可以以角度和距离约束窗口小部件中心相对于另一个窗口小部件中心。这允许您将小部件放在圆上(参见图6)。可以使用以下属性:

  • layout_constraintCircle :引用另一个小部件ID
  • layout_constraintCircleRadius :到其他窗口小部件中心的距离
  • layout_constraintCircleAngle :小部件应该处于哪个角度(以度为单位,从0到360)

图6 - 圆形定位

<Button android:id="@+id/buttonA" ... />
<Button android:id="@+id/buttonB" ...
app:layout_constraintCircle="@+id/buttonA"
app:layout_constraintCircleRadius="100dp"
app:layout_constraintCircleAngle="45" />

可见性行为

ConstraintLayout 具有标记为小部件的特定处理View.GONE。

GONE像往常一样,窗口小部件不会显示,也不是布局本身的一部分(例如,如果标记为实际尺寸,则不会更改它们GONE)。

但就布局计算而言,GONE小部件仍然是其中的一部分,具有重要的区别:

  • 对于布局传递,它们的尺寸将被视为零(基本上,它们将被解析为一个点)
  • 如果他们对其他小部件有限制,他们仍然会受到尊重,但任何边距都会好像等于零

图7 - 可见性行为

这种特定的行为允许构建布局,您可以暂时将小部件标记为GONE,而不会破坏布局(图7),这在进行简单的布局动画时尤其有用。

注意:使用的边距将是B在连接到A时定义的边距(例如,参见图7)。在某些情况下,这可能不是您想要的余量(例如A在其容器侧面有100dp的边距,B只有16dp到A,A标记为已消失,B将有16dp的余量到容器)。因此,您可以指定在连接到标记为已消失的窗口小部件时要使用的备用边距值(请参阅上面有关已删除边距属性的部分)。

尺寸限制

ConstraintLayout 上的最小尺寸

您可以为ConstraintLayout自身定义最小和最大尺寸:

  • android:minWidth 设置布局的最小宽度
  • android:minHeight 设置布局的最小高度
  • android:maxWidth 设置布局的最大宽度
  • android:maxHeight 设置布局的最大高度

ConstraintLayout当尺寸设置 为时,将使用这些最小和最大尺寸WRAP_CONTENT。

小部件维度约束

可以通过以3种不同方式设置android:layout_width和 android:layout_height属性来指定小部件的维度:

  • 使用特定维度(文字值,例如123dp或Dimension参考)
  • 使用WRAP_CONTENT,这将要求小部件计算自己的大小
  • 使用0dp,相当于“ MATCH_CONSTRAINT”

图8 - 尺寸约束

前两个以与其他布局类似的方式工作。最后一个将以匹配所设置的约束的方式调整窗口小部件的大小(参见图8,(a)是wrap_content,(b)是0dp)。如果设置了边距,则在计算中将考虑它们(图8,(c)中的0dp)。

重要提示: MATCH_PARENT不建议用于a中包含的小部件ConstraintLayout。可以通过使用MATCH_CONSTRAINT设置为相应的左/右或上/下约束来定义类似的行为"parent"。

WRAP_CONTENT:强制约束(在1.1中添加)

如果将维度设置为WRAP_CONTENT,则在1.1之前的版本中,它们将被视为文字维度 - 这意味着约束不会限制生成的维度。虽然通常这足够(并且更快),但在某些情况下,您可能希望使用WRAP_CONTENT,但仍然强制执行约束来限制结果维度。在这种情况下,您可以添加一个相应的属性:

  • app:layout_constrainedWidth=”true|false”
  • app:layout_constrainedHeight=”true|false”

MATCH_CONSTRAINT尺寸(1.1中添加)

当维度设置为时MATCH_CONSTRAINT,默认行为是使结果大小占用所有可用空间。还有几个额外的修饰符:

  • layout_constraintWidth_min和layout_constraintHeight_min:将设置此维度的最小大小
  • layout_constraintWidth_max和layout_constraintHeight_max:将设置此维度的最大大小
  • layout_constraintWidth_percent和layout_constraintHeight_percent:将此维度的大小设置为父级的百分比

最小和最大

为min和max指示的值可以是Dp中的维度,也可以是“wrap”,它将使用与其相同的值WRAP_CONTENT。

百分比

要使用百分比,您需要设置以下内容:

  • 尺寸应设置为MATCH_CONSTRAINT(0dp)
  • 默认值应设置为百分比app:layout_constraintWidth_default="percent" 或app:layout_constraintHeight_default="percent"
    (注意:这在1.1-beta1和1.1-beta2中是必需的,但如果定义了percent属性,则在以下版本中不需要)

  • 然后将layout_constraintWidth_percent 或layout_constraintHeight_percent属性设置为0到1之间的值

您还可以将窗口小部件的一个维度定义为另一个维度的比率。为此,您需要将至少一个约束维度设置为0dp(即MATCH_CONSTRAINT),并将该属性layout_constraintDimensionRatio设置为给定比率。例如:

         <Button android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1" />

将按钮的高度设置为与其宽度相同。

该比率可表示为:

  • 浮点值,表示宽度和高度之间的比率
  • “宽度:高度”形式的比率

如果两个尺寸都设置为MATCH_CONSTRAINT(0dp),您也可以使用比率。在这种情况下,系统设置最大尺寸以满足所有约束并保持指定的纵横比。要根据另一个特定边的尺寸约束一个特定边,可以预先附加W,“或” H,分别约束宽度或高度。例如,如果一个尺寸受两个目标约束(例如,宽度为0dp并且以父节点为中心),则可以指示应该约束哪一边,通过 在比率前添加字母W(用于约束宽度)或H(用于约束高度),用逗号分隔:

         <Button android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="H,16:9"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"/>

将按照16:9的比例设置按钮的高度,而按钮的宽度将匹配父项的约束。

链在单个轴(水平或垂直)中提供类似行的行为。另一个轴可以独立约束。

创建一个链

如果一组小部件通过双向连接链接在一起,则它们被视为链(参见图9,显示最小链,具有两个小部件)。

图9 - 链条

链头

图10 - 链头

头部是水平链的最左侧小部件,垂直链的最顶部小部件。

链中的边距

如果在连接上指定了边距,则会考虑它们。在扩散链的情况下,将从分配的空间中扣除保证金。

链式

设置属性layout_constraintHorizontal_chainStyle或layout_constraintVertical_chainStyle链的第一个元素时,链的行为将根据指定的样式(默认值CHAIN_SPREAD)更改。

  • CHAIN_SPREAD - 元素将展开(默认样式)
  • 加权链入CHAIN_SPREAD模式,如果设置了一些小部件MATCH_CONSTRAINT,它们将分割可用空间
  • CHAIN_SPREAD_INSIDE - 类似,但链的端点不会散开
  • CHAIN_PACKED - 链条的元素将被包装在一起。然后,子项的水平或垂直偏差属性将影响打包元素的定位

图11 - 链条样式

加权链

链的默认行为是在可用空间中平均分布元素。如果使用了一个或多个元素MATCH_CONSTRAINT,它们将使用可用的空白空间(在它们之间平均分配)。属性layout_constraintHorizontal_weight和layout_constraintVertical_weight 将控制如何将空间利用的元素之间进行分配MATCH_CONSTRAINT。例如,在包含两个元素的链上使用MATCH_CONSTRAINT,第一个元素使用权重2,第二个元素使用权重1,第一个元素占用的空间将是第二个元素占用的空间的两倍。

边距和链条(1.1)

在链中的元素上使用边距时,边距是相加的。

例如,在水平链上,如果一个元素定义了10dp的右边距,而下一个元素定义了5dp的左边距,则这两个元素之间产生的边距为15dp。

在计算链用于定位项目的剩余空间时,会同时考虑项目及其边距。剩余空间不包含边距。

虚拟助手对象

除了之前详述的内在功能外,您还可以使用特殊的辅助对象ConstraintLayout来帮助您进行布局。目前,该Guideline对象允许您创建相对于ConstraintLayout容器定位的水平和垂直准线。然后可以通过将小部件限制为这样的指导来定位小部件。在1.1中,Barrier也Group被添加了。

优化器(1.1)

在1.1中我们公开了约束优化器。您可以通过将标记app:layout_optimizationLevel添加到ConstraintLayout元素来决定应用哪些优化。

  • none:不应用任何优化
  • 标准:默认。仅优化直接和屏障约束
  • 直接:优化直接约束
  • 障碍:优化障碍限制
  • 链:优化链约束(实验)
  • 维度:优化维度度量(实验),减少匹配约束元素的度量数量

此属性是一个掩码,因此您可以通过列出所需的优化来决定打开或关闭特定的优化。例如:app:layout_optimizationLevel =“direct | barrier | chain”

Android开发之ConstraintLayout相对布局的更多相关文章

  1. Android开发之5大布局方式详解

    Android中常用的5大布局方式有以下几种: 线性布局(LinearLayout):按照垂直或者水平方向布局的组件. 帧布局(FrameLayout):组件从屏幕左上方布局组件. 表格布局(Tabl ...

  2. 【Android UI】Android开发之View的几种布局方式及实践

    引言 通过前面两篇: Android 开发之旅:又见Hello World! Android 开发之旅:深入分析布局文件&又是“Hello World!” 我们对Android应用程序运行原理 ...

  3. Android 开发之旅:深入分析布局文件&又是“Hello World!”

    http://www.cnblogs.com/skynet/archive/2010/05/20/1740277.html 引言 上篇可以说是一个分水岭,它标志着我们从Android应用程序理论进入实 ...

  4. Android开发之旅: Intents和Intent Filters(理论部分)

    引言 大部分移动设备平台上的应用程序都运行在他们自己的沙盒中.他们彼此之间互相隔离,并且严格限制应用程序与硬件和原始组件之间的交互. 我们知道交流是多么的重要,作为一个孤岛没有交流的东西,一定毫无意义 ...

  5. Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab

     今天我们要实现的这个效果呢,在Android的应用中十分地常见,我们可以看到下面两张图,无论是系统内置的联系人应用,还是AnyView的阅读器应用,我们总能找到这样的影子,当我们滑动屏幕时,Tab可 ...

  6. Android开发之Java必备基础

    Android开发之Java必备基础 Java类型系统 Java语言基础数据类型有两种:对象和基本类型(Primitives).Java通过强制使用静态类型来确保类型安全,要求每个变量在使用之前必须先 ...

  7. Android开发之PopupWindow

      /* *  Android开发之PopupWindow * *  Created on: 2011-8-8 *  Author: blueeagle *  Email: liujiaxiang@g ...

  8. android开发之Animations的使用(二)

    android开发之Animations的使用(二) 本博文主要讲述的是android开发中的animation动画效果的使用,和上一篇博文不同的是,此次四种动画效果,主要使用的是xml文件实现的,提 ...

  9. Android开发之旅4:应用程序基础及组件

    引言 为了后面的例子做准备,本篇及接下来几篇将介绍Android应用程序的原理及术语,这些也是作为一个Android的开发人员必须要了解,且深刻理解的东西.本篇的主题如下: 1.应用程序基础 2.应用 ...

随机推荐

  1. MySql系列之单表查询

    单表查询的语法 SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数 关键字的执行 ...

  2. eclipse maven install 时控制台乱码问题解决

    pom.xml文件中加入: <properties> <argLine>-Dfile.encoding=UTF-8</argLine> <project.bu ...

  3. ArcGIS api for javascript——动态创建图层列表

    描述 本例循环地图服务里的所有图层并增加每个图层到一个带checkbox的列表,checkbox能设置图层的显示或隐藏.动态创建列表的优势是所有的图层都会包含在列表中,即使服务器管理员删除或增加了图层 ...

  4. JSR 303 - Bean Validation 简单介绍及用法

    一.JSR-303简单介绍 JSR-303 是 JAVA EE 6 中的一项子规范.叫做 Bean Validation,官方參考实现是Hibernate Validator. 此实现与 Hibern ...

  5. 网络协议 4 - 交换机与 VLAN

    上一次,我们通过公司需求,认识了如何通过物理层和链路层组建一个公司局域网.今天,我们切换到复杂点的办公室场景.     在这个场景里,就不像在大学教室那样,搞几根网线,拉一拉,扯一扯就可以了.一个办公 ...

  6. 用efibootmgr管理UEFI启动项,添加丢失的启动项

    UEFI用来替代传统BIOS引导操作系统,学会修改UEFI启动项也变得十分重要,UEFI全称为:“统一的可扩展固件接口”(Unified Extensible Firmware Interface), ...

  7. js sort()函数 排序问题 var arr =['A-1-5-1','A-1-10-2','A-1-5-5','B-2-3-1','C-4-10-1'], 对这个数组进行排序,想达到的效果是["A-1-5-1", "A-1-5-5", "A-4-10-1", "A-1-10-2", "A-2-3-1"]

    先介绍个方法 charCodeAt() 方法可返回指定位置的字符的 Unicode 编码.这个返回值是 0 - 65535 之间的整数. stringObject.charCodeAt(index) ...

  8. Linux下QQ的使用并手动设置QQ文件保存路径

    一.背景&&目标 马化腾迟迟不肯做linux版本的QQ和微信,实在抠脚. 没有办法,要在linux上使用QQ,目前我找到最好的办法就是使用wine,然而wine这个杀千刀的又是个坑货, ...

  9. GPU-directX的发展历史

    GPU发展历史: GPU之前的基础: 1962 麻省理工学院的博士伊凡•苏泽兰发表的论文以及他的画板程序奠定了计算机图形学的基础. 1962-1984 没有专门图形处理硬件,由CPU完成 1984 专 ...

  10. PHP设置30秒内对页面的访问次数

    <?php //Calculate 60 days in the future //seconds * minutes * hours * days + current time $intime ...