ConstraintLayout基础系列之约束(constraints)

什么是约束(Constraints)

ConstraintLayout 的核心基础就是创建约束。约束定义了布局内两个组件之间的关系,从而控制组件的布局位置。对于刚接触 ConstraintLayout 但对 RelativeLayout 熟悉的开发者来说,约束布局的工作原理很像 RelativeLayout 中通过创建组件间关系来控制布局。

 

android Studio 编辑器中创建约束

最容易创建约束布局的方式是通过 Android Studio 中的 design 可视化布局编辑器。本文章的例子都通过蓝图 Blueprint 视图来查看展示,我们先简单看看在 Blueprint 视图中的 TextView 。

blueprint.png

清晰地可以看到 TextView 组件,以及两个箭头符号表示在这个 TextView 组件上存在约束将它对齐到父组件 ConstraintLayout 的左边缘和上边缘。待会再来看它们是如何创建的,还可以看到存在 16dp 的外边距让父组件 ConstraintLayout 和 TextView 的组件边缘之间保留了一些间隙。选择 TextView 组件就会看到如下的缩放和约束锚点。

anchor_points.png

边角上的小正方形是缩放的控制点,通过拖拉这些点就可以对 TextView 进行缩放。但是这个大多数情况并不是很适用,因为使用这种方式进行缩放后的组件将保持固定的尺寸,而我们往往更需要 TextView 根据具体情况响应式大小。

每条边中间的锚点就是约束锚点,我们就是用这个锚点来创建约束的。其中左边和上边的锚点里面有蓝点表示这个锚点已经存在了一个约束,相对的右边和下边的空心锚点则表示没有约束。从这个例子,我们就可以看到 TextView 的布局位置就通过定义约束来对齐了父组件。

任何继承了 TextView 的子组件都拥有另一个锚点:被称为基线(baseline)。这就允许我们通过该锚点来调整组件内的文字对齐基线。选择 TextView 后出现下方按钮,点击其中的 ab 按钮来显示这个锚点。

baseline.png

在 TextView 上出现香肠状的控制锚点就是基线约束锚点。我们可以通过给这个锚点添加约束就像下面提到给四个边的约束锚点添加约束一样。

另一个出现的下方按钮中是取消约束按钮(按钮中存在 ‘x’ ),点击将移除该组件上的所有约束。

创建锚点,我们只需要简单的从一个组件的锚点,拖动指向到另一个组件 View 的锚点。此处的例子,我们创建另一个 TextView (id 为 textView2 ,原来的那个 id 是 textview),而且 textView2已有一个对齐父组件左边的约束,我们再创建一个约束,从 textView2 的上边到 textview 的下边。而这个约束就会让 textView2 对齐到 textview 正下方,如下所示:

create_constraint.gif

在此处还要注意,我们创建的约束是从 textView2 的上边到 textView 的下边,当我们选择这两个组件的时候,我们只会看到 textView2 的上边约束锚点存在约束,而 textView 的下边约束锚点是空心的不存在约束。

unidirectional.png

这样的原因是约束是单向的(除非我们谈论的约束是链接 chains ),所以这里例子创建的约束是属于 textView2 的,影响的也是 textView2 的布局位置是相对于 textView 的。因为该约束是只属于 textView2 的,反过来不会影响 textView 的布局位置

上面讲到的是同级组件间创建约束,而对于一个组件要创建相对于父组件的约束,则只是简单的将约束拖的方向到合适的父组件边缘即可,如下:

create_parent_constraint.gif

在 XML 中创建约束

对于想了解在可视化布局下真正的存储的是如何的开发者,以下就是 上面例子的 XML 源码:

<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.ConstraintLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context=".MainActivity">

<TextView

android:id="@+id/textView"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginStart="16dp"

android:layout_marginTop="16dp"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintTop_toTopOf="parent"

tools:text="TextView" />

<TextView

android:id="@+id/textView2"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginStart="16dp"

android:layout_marginTop="8dp"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintTop_toBottomOf="@+id/textView"

tools:text="TextView" />

</android.support.constraint.ConstraintLayout>

代码中的约束都是以 app:layout_constraint 开头的属性。我们可以看到 ConstraintLayout 中所有子组件都存在这些属性。让他们对齐父组件的边缘。你还可以看到 textView2 定义了一个约束声明了该组件的上边相对对齐到 textview 的下边。

值得一提的是,这些属性设置都是使用的 app 命名空间因为 ConstraintLayout 是像 Support libraries 也是作为库引入。它属于你的命名空间 app 而不是属于安卓框架(使用命名空间 android )。

删除约束

上面提到我们可以通过选中组件后出现的清空按钮来清除所有的约束。最后,我们还要介绍的是只删除其中一个约束。如果在 XML 源码中可以直接去掉相应的属性。若使用的是可视化编辑器,则通过点击约束锚点来去除约束条件。

delete_constraint.gif

赞 (0) 评论 分享 ()