Android中约束布局ConstraintLayout的API和属性解析

前面我们已经通过一篇文章《约束布局 ConstraintLayout 的使用》 介绍了如何创建和使用约束布局,今天我们来看一下关于约束布局 ConstraintLayout 的 API 属性,更进一步的了解关于约束布局的详细设置。

ConstraintLayout 继承自 android.view.ViewGroup 允许以灵活的方式定位和调整界面组件的大小。ConstraintLayout 是 Android 中的一个 support 库,你可以从 API level 9 (Gingerbread) 开始在Android 系统上使用它。我们可以使用的约束类型有如下几种:

约束布局相对定位

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

  • 横轴: left 左、 right 右、start 起点和 end 终点。
  • 纵轴:top 顶部、bottom 底部和 text baseline 文本基线。

相对定位示例 相对定位示例

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

上面的代码告诉 Android 系统,我们想要将按钮 B 的左侧约束到按钮 A 的右侧。这样的位置约束意味着系统将尝试让两边共享相同的位置。

相对定位的位置示意 相对定位的位置示意

相对定位中我们有下面这些属性可设置:

  • layout_constraintLeft_toLeftOf:B 的左侧约束到 A 的左侧。
  • layout_constraintLeft_toRightOf:B 的左侧约束到 A 的右侧。
  • layout_constraintRight_toLeftOf:B 的右侧约束到 A 的左侧。
  • layout_constraintRight_toRightOf:B 的右侧约束到 A 的右侧。
  • layout_constraintTop_toTopOf:B 的上边约束到 A 的上边。
  • layout_constraintTop_toBottomOf:B 的上边约束到 A 的底边。
  • layout_constraintBottom_toTopOf:B 的底边约束到 A 的上边。
  • layout_constraintBottom_toBottomOf:B 的底边约束到 A 的底边。
  • layout_constraintBaseline_toBaselineOf: B 的文本基线约束到 A 的文本基线。
  • layout_constraintStart_toEndOf:B 的起点约束到 A 的终点。
  • layout_constraintStart_toStartOf:B 的起点约束到 A 的起点。
  • layout_constraintEnd_toStartOf:B 的终点约束到 A 的起点。
  • layout_constraintEnd_toEndOf:B 的终点约束到 A 的终点。

当然这些属性也有与之对应的父组件 parent 的相对位置关系,例如我们将上面例子的 A 换成父容器 parent.

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

设置约束布局的Margin

相对定位 margin 相对定位 margin

设置 margin 将强制填充两个组件之间相对位置的空间,例如上图 B 的左侧约束到 A 的右侧,则我们给 B 设置 android:layout_marginLeft 就可达到图中效果。

对于 margin 还有如下几个属性可设置:

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

设置约束布局偏移量 bias

假如我们有一个小部件约束在 parent 的左侧和右侧,则该部件默认会处于中心位置,代码如下:

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

中心定位 中心定位

遇到这种相反的约束时,默认情况是将小部件居中;但是您可以使用 bias 属性调整定位,使其偏向一边。例如,下面的代码将使左侧具有 30% 的偏差,而不是默认的50%,从而使左侧更短,小部件更倾向于左侧。

1
2
3
4
5
6
<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/>
</>

中心定位 中心定位

总共有两个属性,一个是水平方向,一个是垂直方向来设置这种偏移量:

  • layout_constraintHorizontal_bias
  • layout_constraintVertical_bias

使用这种方法我们可能设计出更利于应对屏幕变化的界面布局。转载请说明出处,本文出自水寒的个人博客:https://dp2px.com

中心点约束(圆心约束)

您可以将小部件中心约束为相对于另一个小部件中心的角度和距离。这允许您将小部件定位在圆上。

中心定位 中心定位

我们需要三个属性来表示这种相对约束关系:

  • layout_constraintCircle: 相关联的另一个组件的 id.
  • layout_constraintCircleRadius: 该组件到另一个组件的圆心的距离。
  • layout_constraintCircleAngle: 小部件应该处于哪个角度(以角度 degrees 为单位,从 0 到 360)。

示例代码如下:

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

中心定位示例 中心定位示例

约束布局可见性 Visible

ConstraintLayout 对标记为 View.GONE 的小部件有特定的处理。像其他布局一样,设置为 GONE 的小部件不会显示,也不是布局本身的一部分(也就是说,如果标记为 GONE,它们的实际尺寸不会改变)。但是在布局计算方面,消失的小部件仍然是它的一部分,这是一个重要的区别,这个组件本身占用的尺寸为 0,而且 margin 也会是 0,但是它和其他组件之间的约束关系是存在的。

中心定位示例 中心定位示例

约束布局的尺寸约束

我们可以给组件自身设置一个最小尺寸,这些属性将在组件使用 wrap_conent 的时候生效:

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

我们可以设置一个组件的 layout_widthlayout_height, 如果设置为 wrap_content 则会由自己的元素撑开并自己计算大小(下图 b), 而如果设置为具体的尺寸,例如 120dip 则会显示指定长度(下图 a),如果我们指定为 0dip 或者 match_constraint 则会填充整个约束(下图 c)。

尺寸约束三种情况示例 尺寸约束三种情况示例

这里需要注意的是,不建议在约束布局中使用 match_parent 而是通过 match_constraint 来代替。

如果我们使用了 wrap_content 约束,还有两个额外属性可以配合使用:

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

如果我们使用了 match_constraint 约束,还有 3 组属性可以配合使用:

  • layout_constraintWidth_min 和 layout_constraintHeight_min : 是否为这个维度设置最小尺寸
  • layout_constraintWidth_max 和 layout_constraintHeight_max : 将为这个维度设置最大尺寸吗
  • layout_constraintWidth_percent 和 layout_constraintHeight_percent : 是否将此维度的大小设置为父维度的百分比

在这里我们不仅仅可以给 min 和 max 设置具体的 dp, 还可以设置成 wrap_content 它将使用与wrap内容相同的值。

如果我们要给组件尺寸设置成百分比的形式,这个组件必须是 match_constraint ,我们可以设置一个默认百分比 app:layout_constraintWidth_default="percent"app:layout_constraintHeight_default="percent", 然后可以设置希望的百分比 layout_constraintWidth_percentlayout_constraintHeight_percent 值是 0 到1 之间。

约束布局设置比率

您还可以将小部件的一个维度定义为另一个维度的比值。为此,您需要至少将一个约束维度设置为 0dp ,并将属性布局约束设置为给定的比例。例如:

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

上面将按钮的高度设置为与其宽度相同,这里的比值可以是浮点值或者是 width:height 的形式。

如果两个维度都设置为匹配约束(0dp),也可以使用比率 Ratio。在这种情况下,系统设置满足所有约束的最大维度,并保持指定的长宽比。要根据另一边的尺寸约束某一边,可以预先附加 W 或 H,分别约束宽度和高度。例如,如果一个维度受到两个目标的约束(例如宽度为 0dp 并以父元素为中心),您可以通过在前面添加字母 W(用于约束宽度)或 H(用于约束高度)来指出应该约束哪边。

1
2
3
4
5
<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 的比例设置按钮的高度,而按钮的宽度将与父元素的约束匹配。

链式约束关系

链式约束关系示意图 链式约束关系示意图

如上图,水平排列的最左边为头组件,而竖直排列的最上面为头组件,我们给头组件设置属性 layout_constraintHorizontal_chainStyle 或者 layout_constraintVertical_chainStyle 链的行为将根据指定的样式进行更改。

  • CHAIN_SPREAD:元素将被展开(默认样式)
  • 权重链:在 CHAIN_SPREAD 模式中,如果将一些小部件设置为匹配约束,它们将分割可用空间。
  • CHAIN_SPREAD_INSIDE:类似的,但是链的端点不会散开。
  • CHAIN_PACKED:链上的元素会被打包在一起。然后,子元素的水平或垂直偏差属性将影响打包元素的位置。

链式约束各种样式 链式约束各种样式

当对链中的元素使用边距时,边距是相加的。例如,在水平链上,如果一个元素定义了一个 10dp 的右边距,而下一个元素定义了一个 5dp 的左边距,那么这两个元素之间的结果边距就是 15dp。当计算链用于放置项的剩余空间时,将项及其边距一并考虑。剩余的空间不包含边距。

哇!终于看完了,不要着急实践,在你动手之前我为你准备了一篇实践的最佳案例和指导,你不妨看看 《看完才知道约束布局 ConstraintLayout 原来这么简单》