一、概述
ConstraintLayout 是一个 ViewGroup,它可以解决复杂布局视图嵌套问题,创建布局一般为平面视图层次结构。跟 ReletiveLayout 很像,所有的 view 通过和相邻的 view 或者 parent layout 之间建立关系来布局,但是比 ReletiveLayout 更加灵活、简单,而且减少绘制。
二、添加约束
// 位置约束
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintLeft_toRightOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintRight_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="parent"
添加了约束之后,对应方向上的 margin 值才有效。下边是几种常用的约束,可以实现不同的布局效果。
- parent 约束
app:layout_constraintLeft_toLeftOf="parent"
- id 约束
app:layout_constraintLeft_toLeftOf="@id/textview2"
- 居中
// 相对与 textview2 左右边界居中
app:layout_constraintLeft_toLeftOf="@id/textview2"
app:layout_constraintRight_toRightOf="@id/textview2"
// 相对 parent layout 居中
app:layout_constraintLeft_toLeftOf="@id/textview2"
app:layout_constraintRight_toRightOf="@id/textview2"
另外可以指定一个 bias,偏移的比例为 0~1,上面居中的情况下,bias 默认为 0.5。
app:layout_constraintHorizontal_bias="0.2"
- Baseline
app:layout_constraintBaseline_toBaselineOf="@id/textview2"
- guideline
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
- barrier
<android.support.constraint.Barrier
android:id="@+id/barrier1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="textview1,textview2" />
guideline 和 barrier 都是用户看不到的,不同的是 guideline 位置固定,然后 barrier 位置会根据所引用的 view 大小变化而变化。
三、调整 View 大小
- 固定值
android:layout_width="24dp"
- wrap content
android:layout_width="wrap_content"
- match constraint
android:layout_width="0dp"
如果设置了 match constraint,那么还可以设定下面几个属性
// 取值 wrap 跟 wrap content 效果差不多
app:layout_constraintWidth_default="spread"
app:layout_constraintWidth_min="20dp"
app:layout_constraintWidth_max="200dp"
- radio
android:layout_width="0dp"
android:layout_height="24dp"
app:layout_constraintDimensionRatio="2:1"
如果指定 view 的宽高比,那么 width 或者 height 有一个必须是 match constraint 方式指定。
四、链(Chains)
Chains 是一组 view,通过双向位置约束来链接,有水平和垂直分布。
<TextView
android:id="@+id/textview21"
android:layout_width="0dp"
android:layout_height="24dp"
android:text="A"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintDimensionRatio="2:1"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/textview22" />
<TextView
android:id="@+id/textview22"
android:layout_width="0dp"
android:layout_height="24dp"
android:background="@color/GBK08A"
android:text="B"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintDimensionRatio="2:1"
app:layout_constraintLeft_toRightOf="@id/textview21"
app:layout_constraintRight_toRightOf="parent" />
一组 view 在垂直或者水平方向双向链接之后,通过在头部 view 上添加下面属性设置 Chain 的样式
app:layout_constraintHorizontal_chainStyle="packed"
chainStyle的取值有 spread、spread-inside、packed、weighted。
spread:所有视图均分 space
spread-inside:两边的视图贴靠边缘,然后所有视图均分 space
packed:所有视图中间没有 space,默认居中显示。如果在头部 view 上添加 bias,则整体移动。
weighted:跟 linearlayout 的 weight 用法差不多。
五、keyframe 动画
keyframe 动画只是 view 的大小和位置发生变化,其他的属性不会变(比如颜色,透明度)。
用法:
- 编写两个 ConstaintLayout 的布局文件,要产生动画的控件 id 需要保持一致。keyframe1.xml、keyframe2.xml。
- 在代码中产生动画
fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.keyframe_one)
constraintLayout = findViewById(R.id.asdasd)
}
fun animateToKeyframeTwo() {
val constraintSet = ConstraintSet()
constraintSet.load(this, R.layout.keyframe2)
TransitionManager.beginDelayedTransition();]
constraintLayout.apply(constraintSet)
}