什么是约束(Constraints)
创建约束是ConstrainLayout
基本视图构建的一部分,约束定义了布局中两个视图组件之间的关系,并且控制这些视图组件在布局中的位置。对于ConstrainLayout
的这些新特性,其实和RelativeLayout
的约束原理是非常类似的。
在可视化编辑器中创建约束
学习如何创建约束的最简单的方法就是使用Android Studio
中的可视化编辑器,我们首先来看一个有关TextView
的简单例子:
从上图可明显的看出,两个箭头表示的就是约束代表将左边缘和顶部对齐父组件ConstrainLayout
,并分别都是16dp的边距,如果我们鼠标点击选中TextView
,我们将看到有关尺寸和锚点:
上图矩形的四个角(实心小正方形)代表尺寸的句柄,我们可以拖动它们来调整TextView
的大小。但是这种方式并不是经常使用,最好的方式就是让TextView
通过某种方式来进行响应改变大小。
每个边缘中间的圆是锚点,用于创建约束。左边和上边的锚点包含一个实心圆代表此锚点已经定义了约束,而另外两个空心圆锚点则代表未实现约束。由此我们可以通过顶部和左边缘与父布局对齐来定义TextView
的位置。
任何TextView
的子类都将有一个附加类型的锚点:基线(baseline)。通过它我们在TextView
中对齐文本的基线,可以点击TextView
下方的ab
按钮来查看:
那个长椭形(香肠状)的就是基线的锚点,在基线上创建约束的方式和四个边缘锚点创建的方式是一样的。
TextView
基线左边的按钮(包含x
的按钮)将会删除所有的约束。
要创建约束,我们只需要抓住一个View
上的锚点,并将其拖动到另一个View
的锚点之上就行。这里我们在原来的例子中再添加一个TextView
,它具有一个左边缘的约束对齐父布局,并且我们从第二个TextView
的顶部创建一个约束拖动至第一个TextView
的底部边缘的锚点上,这就使第二个TextView
位于第一个TextView
的下方:
有一点值得注意的是,虽然我们已经从textView2
的顶部到textView1
的底部创建了一个约束,但是如果我们选中两个TextView
后仔细观察,我们会发现,textView2
顶部已附加一个约束,但textView1
却并没有约束(textView1
的底部锚点还是空心的):
原因是因为约束是单一的约束(链(chains)是特殊的情况),所以在这个问题中,约束是附加给textView2
的,并且它是相对于textView1
来进行定位的,由于约束至附加到textView2
,所以他对textView1
的定位是没有直接的影响。
现在我们已经知道如何在View
之间创建一个约束,那我们如何去在View
与父布局之间创建约束呢?其实很简单,只需要将锚点拖动到父布局的边缘即可:
在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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="16dp"
android:id="@+id/textView1"/>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@+id/textView1"/>
</android.support.constraint.ConstraintLayout>
属性约束是以:app:layout_constraint
开头的,从上图代码可看出,ConstraintLayout
的所有子视图都是有相对于父布局的布局定位,还有textView2
还指定了视图顶部相对于textView1
底部定位的约束。
值得注意的是,它们都是在app
的命名空间中,因为ConstraintLayout
是作为库导入的。和支持库一样,它成为了我们应用程序中的一部分,而不是android框架的一部分(使用android
命名空间)。
删除一个约束
最后介绍一下如何删除一个约束,如果是直接使用的XML,则只需要将属性本身删了即可。如果使用的是可视化编辑器,可以通过单击其锚点来删除某个约束: