如何动画约束布局上的嵌套视图?

Bal*_*ian 7 android android-animation android-constraintlayout

我有一个要求,其中视图需要位于底部的中心并根据其内容调整高度。因此constraint layout在 root 内部创建constraint layout以实现此目的。但现在我面临动画问题。我无法申请constraintSet

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#BEE">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/error_layout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="12dp"
        android:layout_marginEnd="12dp"
        android:layout_marginBottom="40dp"
        android:background="#FFF"
        android:visibility="visible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <Button
            android:id="@+id/error_try_again"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="12dp"
            android:layout_marginTop="6dp"
            android:layout_marginEnd="12dp"
            android:layout_marginBottom="12dp"
            android:textStyle="bold"
            android:minWidth="180dp"
            android:text="Try again"
            android:textAlignment="center"
            android:textColor="#000"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/error_subtitle" />

        <TextView
            android:id="@+id/error_title"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="12dp"
            android:layout_marginTop="12dp"
            android:layout_marginEnd="12dp"
            android:textStyle="bold"
            android:text="We are unable to find the object"
            android:textAlignment="center"
            android:textColor="@color/black"
            android:textSize="21sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/error_subtitle"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="12dp"
            android:layout_marginTop="6dp"
            android:layout_marginEnd="12dp"
            android:text="Try to keep the camera steady"
            android:textAlignment="center"
            android:textColor="@color/black"
            android:textSize="12sp"
            android:visibility="visible"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/error_title" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)
  • 如果我需要去 constraintSet如何重组我的布局(没有嵌套组)?
  • 有没有其他方法可以实现它?我觉得使用起来constraintSet非常简单。

尝试调用此动画约束集,它将嵌套约束作为 param 传递error_layout。但结果没有变化:

    private void animateResult(ConstraintLayout constraint) {
        ConstraintSet constraintSet = new ConstraintSet();
        constraintSet.clone(this, R.layout.frameout_layout);

        Transition transition = new ChangeBounds();
        transition.setInterpolator(new AnticipateOvershootInterpolator(1.0f));
        transition.setDuration(1200);
        TransitionManager.beginDelayedTransition(constraint, transition);

        constraintSet.applyTo(constraint);
    }
Run Code Online (Sandbox Code Playgroud)

布局:

在此处输入图片说明

Lal*_*dar 7

请记住,ConstraintSet 动画与任何其他具有两个阶段的动画一样工作 - 动画开始和动画结束。所以,首先将视图约束设置为动画开始,这意味着隐藏在布局的底部。

因此,将初始约束更改为:

<!-- Here app:layout_constraintTop_toBottomOf will position the view under the layout/screen -->
<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/error_layout"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="12dp"
    android:layout_marginEnd="12dp"
    android:layout_marginBottom="40dp"
    android:background="#fff"
    android:visibility="visible"
    app:layout_constraintTop_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent">
Run Code Online (Sandbox Code Playgroud)

然后,将约束创建为

//rootLayout is the Id of the parent layout
val constraintSet = ConstraintSet()
constraintSet.clone(rootLayout)
constraintSet.clear(error_layout.id, ConstraintSet.TOP)
constraintSet.connect(error_layout.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)
val transition: Transition = ChangeBounds()
transition.interpolator = AnticipateOvershootInterpolator(1.0f)
transition.duration = 1200
TransitionManager.beginDelayedTransition(rootLayout, transition)
constraintSet.applyTo(rootLayout)
Run Code Online (Sandbox Code Playgroud)

然后,如果您想再次隐藏它。只需将 TOP 和 BOTTOM 替换为

constraintSet.clear(error_layout.id, ConstraintSet.BOTTOM)
constraintSet.connect(error_layout.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

GIF 比编码花费的时间更多:p。

编辑- 要收听动画更新,尤其是按要求结束动画,您可以做的是将侦听器设置transition

transition.addListener(object : Transition.TransitionListener {
    override fun onTransitionStart(transition: Transition) {
    }
    override fun onTransitionEnd(transition: Transition) {
    }
    override fun onTransitionCancel(transition: Transition) {
    }
    override fun onTransitionPause(transition: Transition) {
    }
    override fun onTransitionResume(transition: Transition) {
    }
})
Run Code Online (Sandbox Code Playgroud)

把它放在beginDelayedTransition().