ConstraintHelper
ConstraintLayout在 1.0 的时候提供了 GuideLine 辅助布局,在 1.1 时提供了 Group 和 Barrier,在 2.0 时候提供了Layer以及放开了限制,开发者可以自定义 Helper 了。
Group (Added in 1.1)
Group可以用来控制一组view的可见性
<android.support.constraint.Group
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="button4,button9" />
可以通过控制 group 的 hide/show 来直接控制一组 view(button4,button9) 的可见性。
Barrier (Added in 1.1)
来看一个场景,下面是一个表单,Email 和 Password 左对齐 中间的虚线为 GuideLine,具体字段都和GuideLine左对齐。

现在如果需要做多语言,翻译为德文后变成了下面的效果

这时候就需要Barrier出场了,Barrier是栅栏的意思,可以理解为挡着不让超过。

改进方法
- 把中间的虚线GuideLine换成Barrier
- 把①和②加入到Barrier的referenced_ids中
- 指定barrierDirection为right(右侧不超过)
- 把③和④左边对齐到Barrier的右边
这样 Email 和 Password就不会超出Barrier,大致代码如下(有删减,完整代码参考这里)
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout>
<TextView
android:id="@+id/tv_email"
app:layout_constraintBottom_toTopOf="@+id/tv_password"
app:layout_constraintStart_toStartOf="@+id/tv_password"
app:layout_constraintTop_toTopOf="parent"
tools:text="E-mail Addresse" />
<EditText
android:id="@+id/et_email"
android:text="me@gmail.com"
app:layout_constraintBaseline_toBaselineOf="@+id/tv_email"
app:layout_constraintStart_toEndOf="@+id/barrier" />
<TextView
android:id="@+id/tv_password"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_email" />
<EditText
android:id="@+id/et_password"
android:inputType="textPassword"
android:text="2321321"
app:layout_constraintBaseline_toBaselineOf="@+id/tv_password"
app:layout_constraintStart_toEndOf="@+id/barrier" />
<android.support.constraint.Barrier
android:id="@+id/barrier"
app:barrierDirection="right"
app:constraint_referenced_ids="tv_email,tv_password" />
</android.support.constraint.ConstraintLayout>
Layer (Added in 2.0)
Layer 可以看作是它引用的 view 的边界(可以理解为包含这些 view 的一个 ViewGroup,但是Layer并不是ViewGroup,Layer并不会增加 view 的层级)。另外Layer支持对里面的 view 一起做变换。
考虑这么一个场景,如果一个页面里面有部分 view 需要加个背景,使用Layer引用这几个 view,然后给Layer设置背景就可以了。如果不用Layer,只能另外加个 ViewGroup 包住这几个 View 了,这样会增加 view 的层级,不利于性能。
看一个示例(完整代码):

图中Layer包住了中间的 6 个按钮,绿色边线白色填充是通过 Layer设置背景完成的。另外对Layer里面的所有按钮一起做动画,出来的效果就是这样子
ConstraintLayout2.0 除了提供几个默认实现的ConstraintHelper外,还提供开发者自定义ConstraintHelper的方式。
自定义 Helper
为什么需要自定义?
- 保持 view 的层级不变,不像 ViewGroup 会增加 view 的层级
- 封装一些特定的行为,方便复用
- 一个 View 可以被多个 Helper引用,可以很方便组合出一些复杂的效果出来
如何自定义?
- Helper持有 view 的引用,所以可以获取 view (getViews)然后操作 view
- 提供了 onLayout 前后的 callback(updatePreLayout/updatePreLayout)
- Helper 继承了 view,所以Helper本身也是 view
CircularRevealHelper

对一张图片作出CircularReveal的效果
ViewAnimationUtils给我们提供了createCircularReveal这个函数
public static Animator createCircularReveal(View view,
int centerX, int centerY, float startRadius, float endRadius)
借助这个函数只需要计算出中心点(centerX,centerY)和 en