1.介绍
约束布局ConstraintLayout 是一个ViewGroup,可以在Api9以上的Android系统使用它,它的出现主要是为了解决布局嵌套过多的问题,以灵活的方式定位和调整小部件。
官方文档 https://developer.android.google.cn/reference/android/support/constraint/ConstraintLayout
2.为什么要用ConstraintLayout
在开发过程中经常能遇到一些复杂的UI,可能会出现布局嵌套过多的问题,嵌套得越多,设备绘制视图所需的时间和计算功耗也就越多。
有些人考虑到了嵌套布局带来的风险,所以用一个RelativeLayout来装下所有的控件。那么问题来了,既然用RelativeLayout可以解决问题,为什么还要使用ConstraintLayout呢?因为ConstraintLayout使用起来比RelativeLayout更灵活,性能更出色!还有一点就是ConstraintLayout可以按照比例约束控件位置和尺寸,能够更好地适配屏幕大小不同的机型。
3.如何使用ConstraintLayout
3.1 添加依赖
首先我们需要在app/build.gradle文件中添加ConstraintLayout的依赖,如下所示。
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
3.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_constraintBaseline_toBaselineOf 相对于某个布局居中
layout_constraintStart_toEndOf
layout_constraintStart_toStartOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf
注:当前view的某个位置从(相对)某个View的相对位置开始绘制
3.3居中(可以相对于父布局也可以相对于某个布局)
app:layout_constraintLeft_toLeftOf="parent" 居左
app:layout_constraintRight_toRightOf="parent" 居右
app:layout_constraintBottom_toBottomOf="parent" 居下
app:layout_constraintTop_toTopOf="parent" 局顶
3.4角度定位
app:layout_constraintCircle="@+id/TextView1"
app:layout_constraintCircleAngle="120"(角度)
app:layout_constraintCircleRadius="150dp"(距离)
指的是TextView2的中心在TextView1的中心的120度,距离为150dp
3.5 goneMargin
goneMargin主要用于约束的控件可见性被设置为gone的时候使用的margin值,属性如下:
layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
3.6 偏移
layout_constraintHorizontal_bias 水平偏移
layout_constraintVertical_bias 垂直偏移
eg: app:layout_constraintHorizontal_bias="0.3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
假如现在要实现水平偏移,给TextView1的layout_constraintHorizontal_bias赋一个范围为 0-1 的值,假如赋值为0,则TextView1在布局的最左侧,假如赋值为1,则TextView1在布局的最右侧,假如假如赋值为0.5,则水平居中,假如假如赋值为0.3,则更倾向于左侧。
垂直偏移同理
3.7 尺寸约束
(1)使用 0dp (MATCH_CONSTRAINT)
官方不推荐在ConstraintLayout中使用match_parent,可以设置 0dp (MATCH_CONSTRAINT) 配合约束代替match_parent,举个例子:
android:layout_width="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
(2)宽高比
当宽或高至少有一个尺寸被设置为0dp(宽或者高)时,可以通过属性layout_constraintDimensionRatio设置宽高比,举个例子:
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
(3)链加权重以及平分布局
如果两个或以上控件通过下图的方式约束在一起,就可以认为是他们是一条链(图为横向的链,纵向同理)
eg: 3个TextView相互约束,两端两个TextView分别与parent约束,成为一条链
一条链的第一个控件是这条链的链头,我们可以在链头中设置 layout_constraintHorizontal_chainStyle来改变整条链的样式。chains提供了3种样式,分别是:
CHAIN_SPREAD —— 展开元素 (默认);
CHAIN_SPREAD_INSIDE —— 展开元素,但链的两端贴近parent;
CHAIN_PACKED —— 链的元素将被打包在一起。
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/TextView2"
android:text="TextView1"
android:padding="10dp"
android:background="#83E9C1"
tools:ignore="MissingConstraints" />
<TextView
android:id="@+id/TextView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@+id/TextView1"
app:layout_constraintRight_toLeftOf="@+id/TextView3"
android:text="TextView2"
android:padding="10dp"
android:background="#B4D9F8"
app:layout_constraintHorizontal_weight="1"
tools:ignore="MissingConstraints" />
<TextView
android:id="@+id/TextView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@+id/TextView2"
app:layout_constraintRight_toRightOf="parent"
android:text="TextView3"
android:padding="10dp"
android:background="#C4E607"
app:layout_constraintHorizontal_weight="2"
tools:ignore="MissingConstraints" />