目录
介绍
ContraintLayout是一个android.view.VBiewGroup,可以在系统Api 9以上使用,它的出现主要是为了解决布局嵌套过多的问题。从Android Studio 2.3 起,官方模板默认使用ConstraintLayout
为什么使用ContraintLayout
在绘制复杂UI时,由于Android绘制视图是根据Z-Order机制,一层层迭代绘制,如果布局嵌套过多,UI层级过深,设备在绘制时所需的时间以及计算功耗就会过多,内存占用也就越多,由于绘制是在UI线程执行,而UI线程不能做耗时操作,所以就需要减少布局嵌套过多。
普通的LinearLayout和RelativeLayout,在绘制简单的布局时可以使用,但是在复杂的布局时,就会出现嵌套问题。而ConstraintLayout属于扁平化处理,可以按照比例约束控件位置和尺寸,因此在Android碎片化如此严重的情况下,这个特点太重要了。
如何使用ConstraintLayout
- 添加依赖
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
- 相对定位
常用的相对属性
app:layout_constraintLeft_toLeftOf="parent" // 当前控件与其父布局左对齐
app:layout_constraintLeft_toRightOf="parent" // 当前控件左与其父布局右对齐,若父布局设置了width,则子控件会不可见
app:layout_constraintRight_toLeftOf="parent" // 当前控件右与其父布局左对齐,若父布局设置了width,则子控件会不可见
app:layout_constraintRight_toRightOf="parent" // 当前控件与其父布局右对齐
app:layout_constraintTop_toTopOff="parent" // 当前控件与其父布局顶部对齐
app:layout_constraintBottom_toBottomOf="parent" // 当前控件与其父布局底部对齐
app:layout_constraintTop_toBottomOff="other" // 当前控件在other底部
app:layout_constraintBottom_toTopOf="other" // 当前控件在other顶部部
app:layout_constraintStart_toEndOf
app:layout_constraintStart_toStartOf
app:layout_constraintEnd_toStartOf
app:layout_constraintEnd_toEndOf
app:layout_constraintBaseline_toBaselineOf="other" // 当前控件与other的内容水平对齐
- 角度定位
app:layout_constraintCircleRadius="120dp" // 两控件的中心距离
app:layout_constraintCircleAngle="225" // 角度范围[0,360]
app:layout_constraintCircle="@id/key_three" // 参照控件
- 边距
- 使用Margin
与平常使用没有两样,只是必须要约束控件的位置,否则没又效果,编译时就会提醒 - goneMargin
根据名称可知,在有相对约束时,参照控件gone时,该控件的margin属性才生效
- 居中和偏移
- 居中
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
- 偏移
注意:单独使用bias不能实现偏移,必须在居中的情况下,才能实现偏移效果
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.3" // 水平方向,距离坐部0.3总长距离
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3" // 垂直方向,距离顶部0.3总长距离
- 尺寸约束
- 使用指定的dp
- 使用wrap_content 根据内容自己计算大小,不能超过父布局大小。注意!!!ConstraintLayout为1.1版本以下时,使用这种属性要加上强制约束: app:constrainedWidth=”true” app:constrainedHeight=”true”
- 使用0dp
官方不建议在ConstraintLayout中使用Match_Parent,可以使用0dp与约束代替。
<TextView
android:layout_width="0dp"
android:layout_height="60dp"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="afaefaef"
android:textColor="#FFFFFF"
android:textSize="48sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
- 设置宽高比
当宽和高至少有一个设置为0dp时,可以使用 layout_constraintDimensionRatio 设置宽高比
app:layout_constraintDimensionRatio="1:1" // 展示为正方形
app:layout_constraintDimensionRatio="H,2:1" // width:height = 2:1
- 链
在实现等宽分割布局时,普通的做法是使用LinearLayout,设置weight属性,按权重分割,但是weight会影响计算难度,增加耗时。而ConstraintLayout可以通过属性 Chain 实现该功能。
样式链在链的头结点设置。
app:layout_constraintHorizontal_chainStyle="spread" // 水平居中,等分
app:layout_constraintHorizontal_chainStyle="spread_inner" //水平居中,两头重
app:layout_constraintHorizontal_chainStyle="packed" // 水平居中,扎堆存在
// 以下实现垂直居中,水平等分效果
<TextView
android:id="@+id/first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="First"
android:textColor="#FFFFFF"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/second"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="second"
android:textColor="#FFFFFF"
android:textSize="30sp"
app:layout_constraintBaseline_toBaselineOf="@id/first"
app:layout_constraintLeft_toRightOf="@id/first"
app:layout_constraintRight_toLeftOf="@id/Three"
/>
<TextView
android:id="@+id/Three"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Three"
android:textColor="#FFFFFF"
android:textSize="30sp"
app:layout_constraintLeft_toRightOf="@id/second"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBaseline_toBaselineOf="@id/first"/>
辅助工具
- Optimizer
在ContraintLayout 1.1中,设置MATCH_CONSTRAINT时,ConstraintLayout会对控件测量2次。可以使用 app:layout_optimizationLevel 进行优化。 - Barrier
某一控件与一组大小不规则控件的对齐方式。
app:barrierDirection // 屏障所在的位置
app:constraint_referenced_ids // 屏障所参照的控件,取最长边位置
<TextView
android:id="@+id/barrier_one"
android:layout_width="100dp"
android:layout_height="60dp"
android:background="#ffffff"
android:gravity="center"
android:text="barrier_one"
android:textColor="#000000"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3" />
<TextView
android:id="@+id/barrier_two"
android:layout_width="150dp"
android:layout_height="60dp"
android:background="#ffffff"
android:gravity="center"
android:text="barrier_two"
android:textColor="#000000"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1" />
<android.support.constraint.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:barrierDirection="right"
app:constraint_referenced_ids="barrier_one,barrier_two"
/>
<TextView
android:id="@+id/barrier_three"
android:layout_width="150dp"
android:layout_height="60dp"
android:background="#ffffff"
android:gravity="center"
android:text="barrier_three"
android:textColor="#000000"
android:textSize="18sp"
app:layout_constraintLeft_toRightOf="@id/barrier"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
- Group
把多个控件归为一组,方便隐藏或显示组内的控件.
可以实现:水平等分布局时,隐藏其中一个,另外几个还会继续保持等分。
<android.support.constraint.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
app:constraint_referenced_ids="barrier_one,barrier_two"/>
- Placeholder
先占位,然后用 app:content 指定要替代的控件。缺点会自带灰色背景。 - Guideline 绘制布局时的辅助线,另一种称呼为法线。它不在屏幕上显示。
总结
ConstraintLayout可以实现产品各种各样的需求,前提是,从使用LinearLayout和RelativeLayout的舒适区中拔出自己,参与到ConstraintLayout的工作中。相信ConstraintLayout不会令你失望!!!