ConstraintLayout(约束布局)开发指南

ConstraintLayout

ConstraintLayout 是一个使用“相对定位”灵活地确定组件的位置和大小的一个布局,解决开发中过于复杂的页面层级嵌套过多的问题——层级过深会增加绘制界面需要的时间。

1、基本约束

1.1 相对定位

相对定位是在 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_constraintStart_toEndOf
layout_constraintStart_toStartOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf

<!--文案基线对齐-->
layout_constraintBaseline_toBaselineOf

它们都引用id另一个控件,或parent(将引用父容器,即 ConstraintLayout)

1.2 边距

在这里插入图片描述

图 3 - 相对定位边距

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

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

请注意,边距只能为正数或等于零,并且取Dimension.

1.3 连接到 GONE 控件时的边距

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

layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
layout_goneMarginBaseline
可见性行为

ConstraintLayout对标记为 的控件进行了特定处理View.GONE。

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

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

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

图 7 - 可见性行为
这种特定行为允许构建布局,您可以在其中临时将控件标记为 is GONE,而不会破坏布局(图 7),这在制作简单布局动画时特别有用。

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

1.4 居中定位和偏移 (Centering positioning and bias)

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

<androidx.constraintlayout.widget.ConstraintLayout ...>
             <Button android:id="@+id/button" ...
                 app:layout_constraintLeft_toLeftOf="parent"
                 app:layout_constraintRight_toRightOf="parent"/>
         </>
         
     

除非ConstraintLayout恰好与 具有完全相同的大小,Button否则不能同时满足两个约束(双方不能在我们想要的位置)。
图 4 - 居中定位
在这种情况下发生的情况是,约束就像相反的力一样将控件拉开(图 4);这样控件最终将在父容器中居中。这同样适用于垂直约束。

偏移(bias)

遇到这种相反约束时的默认设置是将控件居中;但是您可以使用偏移属性调整定位以偏向另一侧:

layout_constraintHorizontal_bias
layout_constraintVertical_bias

例如,

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

       

例如,以下将使左侧具有 30% 的偏移,而不是默认的 50%,这样左侧会更短,


更倾向于左侧(图 5):

图 5 - 偏心定位
类似:LinearLayout 权重分配,适应屏幕尺寸变化小菜一碟了

1.5 圆形定位(1.1中增加)

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

layout_constraintCircle: 引用另一个控件 id
layout_constraintCircleRadius: 到另一个控件中心的距离
layout_constraintCircleAngle: 控件应该在哪个角度(以度为单位,从 0360

在这里插入图片描述

图 6 - 圆形定位

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

1.6 尺寸约束

尺寸约束

android:layout_width可以通过 3 种不同方式设置和 android:layout_height属性 来指定控件的尺寸:

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

图 8 - 尺寸约束
前两个以与其他布局类似的方式工作。最后一个将以匹配设置的约束的方式调整控件的大小(参见图 8,(a)是 wrap_content,(b)是 0dp)。如果设置了边距,它们将在计算中被考虑(图 8,(c)与 0dp)。
重要提示: MATCH_PARENT不建议用于ConstraintLayout. 可以通过MATCH_CONSTRAINT将相应的左/右或上/下约束设置为来定义类似的行为"parent"。

ConstraintLayout 上的最小尺寸

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

  • android:minWidth设置布局的最小宽度
  • android:minHeight设置布局的最小高度
  • android:maxWidth设置布局的最大宽度
  • android:maxHeight设置布局的最大高度
    ConstraintLayout当其尺寸设置为 时, 将使用这些最小和最大尺寸WRAP_CONTENT
WRAP_CONTENT :强制约束(在1.1中添加)

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

  • app:layout_constrainedWidth=“true|false”
  • app:layout_constrainedHeight=“true|false”
MATCH_CONSTRAINT维度(添加在 1 . 1中)
  • 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”
  • 然后将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 - 链条

链头

链由设置在链的第一个元素(链的“头”)上的属性控制:

图 10 - 链头
头部是水平链的最左侧控件,垂直链的最顶部控件。

链中的边距

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

链式

当设置属性layout_constraintHorizontal_chainStyle或layout_constraintVertical_chainStyle在链的第一个元素上时,链的行为将根据指定的样式发生变化(默认为CHAIN_SPREAD)。

  1. CHAIN_SPREAD-- 元素将被展开(默认样式)
  2. 加权链 - 在CHAIN_SPREAD模式下,如果某些控件设置为MATCH_CONSTRAINT,它们将分割可用空间
  3. CHAIN_SPREAD_INSIDE-- 类似,但链的端点不会散开
  4. CHAIN_PACKED-- 链的元素将被打包在一起。子元素的水平或垂直偏差属性将影响打包元素的定位

在这里插入图片描述

加权链

链的默认行为是将元素平均分布在可用空间中。如果一个或多个元素正在使用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:不应用优化
  • 标准:默认。仅优化直接约束和障碍约束
  • direct:优化直接约束
  • 障碍:优化障碍约束
  • 链:优化链约束(实验)
  • 维度:优化维度度量(实验性),减少匹配约束元素的度量数量

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值