1. 介绍
约束布局ConstraintLayout 是一个ViewGroup,可以在Api9以上的Android系统使用它,它的出现主要是为了解决布局嵌套过多的问题,以灵活的方式定位和调整小部件。从 Android Studio 2.3 起,官方的模板默认使用 ConstraintLayout。
官方文档:ConstraintLayout
2. 基本属性及其使用
要在 ConstraintLayout 中定义某个视图的位置,必须为该视图添加至少一个水平约束条件和一个垂直约束条件。每个约束条件均表示与其他视图、父布局或隐形引导线之间连接或对齐方式。每个约束条件均定义了视图在竖轴或者横轴上的位置;因此每个视图在每个轴上都必须至少有一个约束条件,但通常情况下会需要更多约束条件。
2.1 相对定位
1. layout_constraintLeft_toLeftOf
当前View的左侧和另一个View的左侧位置对齐
与RelativeLayout的alignLeft属性相似
2. layout_constraintLeft_toRightOf
当前view的左侧会在另一个View的右侧位置
与RelativeLayout的toRightOf属性相似
3. layout_constraintRight_toLeftOf
当前view的右侧会在另一个View的左侧位置
与RelativeLayout的toLeftOf属性相似
4. layout_constraintRight_toRightOf
当前View的右侧和另一个View的右侧位置对其
与RelativeLayout的alignRight属性相似
5. layout_constraintTop_toTopOf
头部对齐,与alignTop相似
6. layout_constraintTop_toBottomOf
当前View在另一个View的下侧 与below相似
7. layout_constraintBottom_toTopOf
当前View在另一个View的上方 与above相似
8. layout_constraintBottom_toBottomOf
底部对齐,与alignBottom属性相似
9. layout_constraintBaseline_toBaselineOf
文字底部对齐,与alignBaseLine属性相似
10. layout_constraintStart_toEndOf
同left_toRightOf
11. layout_constraintStart_toStartOf
同left_toLeftOf
12. layout_constraintEnd_toStartOf
同right_toLeftOf
13. layout_constraintEnd_toEndOf
同right_toRightOf
2.2 角度定位
layout_constraintCircle : 引用另一个小部件 id
layout_constraintCircleRadius : 到另一个小部件中心的距离
layout_constraintCircleAngle : 小部件应该在哪个角度(以度为单位,从 0 到 360)
<TextView
android:id="@+id/textView1"
.../>
<TextView
android:id="@+id/textView2"
...
app:layout_constraintCircle="@+id/textView1"
app:layout_constraintCircleAngle="120"
app:layout_constraintCircleRadius="150dp"/>
2.3 边距
android:layout_marginStart //距离开始
android:layout_marginEnd //距离结束
android:layout_marginLeft //距离左边
android:layout_marginTop //距离上边
android:layout_marginRight //距离右边
android:layout_marginBottom //距离下边
android:layout_marginBaseline //距离基线
看起来跟别的布局没有什么差别,但实际上控件在ConstraintLayout里面要实现margin,必须先约束该控件在ConstraintLayout里的位置,举个例子:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#E8C99B"
android:gravity="center"
android:text="textview1"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
android:layout_marginLeft="100dp"
android:layout_marginTop="100dp"/>
</android.support.constraint.ConstraintLayout>
不可见性行为(goneMargin)
goneMargin主要用于约束的控件可见性被设置为gone的时候使用的margin值,属性如下:
layout_goneMarginStart //距离开始
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
2.4居中和偏移
//垂直居中
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
//水平居中
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
//垂直水平居中
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
layout_constraintHorizontal_bias //水平方向偏移
layout_constraintVertical_bias //垂直方向偏移
2.5 尺寸约束
- 使用指定的尺寸
- 使用wrap_content,让控件自己计算大小
当控件的高度或宽度为wrap_content时,可以使用下列属性来控制最大、最小的高度或宽度:
android:minWidth 最小的宽度
android:minHeight 最小的高度
android:maxWidth 最大的宽度
android:maxHeight 最大的高度
- 使用 0dp (MATCH_CONSTRAINT)
官方不推荐在ConstraintLayout中使用match_parent,可以设置 0dp (MATCH_CONSTRAINT) 配合约束代替match_parent,举个例子:
<TextView
android:id="@+id/TextView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
......
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
- 宽高比
当宽或高至少有一个尺寸被设置为0dp时,可以通过属性layout_constraintDimensionRatio设置宽高比,举个例子:
<TextView
android:id="@+id/TextView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
......
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constrainedWidth="true"
app:layout_constrainedHeight="true"/>
2.6 链
每一条链的第一个控件是这条链的链头,我们可以在链头中设置layout_constraintHorizontal_chainStyle属性改变整条链的样式。
chains提供了3种样式,分别是:
spread 展开元素 (默认)
spread_inside 展开元素,但链的两端贴近parent
packet 链的元素将被打包在一起。
2.7 权重
layout_constraintHorizontal_weight
假如我们想要这样的效果:两个TextView 平分屏幕,权重1:1
注意点:
1.这两个TextView的 android:layout_width="0dp"
2.这两个TextView的 app:layout_constraintHorizontal_weight="1"
3.这两个TextView互相加约束
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/tv2"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintLeft_toRightOf="@+id/tv1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
2.8 layout_optimizationLevel
layout_optimizationLevel是一个标签,用于配置优化级别。它的可选值如下:
barriers:找出xml中的屏障,并用简单的约束取代它们
direct:优化那些直接连接到固定元素的元素,例如屏幕边缘或引导线,并继续优化直接连接到它们的任何元素。
standard:这是包含 barriers 和 direct 的默认优化级别。
dimensions:通过计算维度来优化布局传递。
chains:计算出如何布置固定尺寸的元素链。
使用方法如下:
<android.support.constraint.ConstraintLayout
app:layout_optimizationLevel="standard|dimensions|chains"
3. Group
Group可以把多个控件归为一组,方便隐藏或显示一组控件
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="tv1,tv2,tv3" />
4. Placeholder
Placeholder指的是占位符。在Placeholder中可使用setContent()设置另一个控件的id,使这个控件移动到占位符的位置。
特殊的是这个属性:app:content = "@+id/tv1"
<androidx.constraintlayout.widget.Placeholder
android:layout_width="wrap_content"
android:id="@+id/placeholder"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:content = "@+id/tv1"
android:layout_height="wrap_content"/>
5. Guideline
Guideline是只能用在ConstraintLayout布局里面的一个工具类,用于辅助布局,类似为辅助线,可以设置android:orientation属性来确定是横向的还是纵向的。
- 当设置为vertical的时候,Guideline的宽度为0,高度是parent也就是ConstraintLayout的高度
- 同样设置为horizontal的时候,高度为0,宽度是parent的宽度
重要的是Guideline是不会显示到界面上的,默认是GONE的。
Guideline还有三个重要的属性,每个Guideline只能指定其中一个:
- layout_constraintGuide_begin,指定左侧或顶部的固定距离,如100dp,在距离左侧或者顶部100dp的位置会出现一条辅助线
- layout_constraintGuide_end,指定右侧或底部的固定距离,如30dp,在距离右侧或底部30dp的位置会出现一条辅助线
- layout_constraintGuide_percent,指定在父控件中的宽度或高度的百分比,如0.8,表示距离顶部或者左侧的80%的距离。
6.Barrier 约束屏障
参考:大佬的博客