【问题标题】:How to animate the nested view on constraint layout?如何在约束布局上为嵌套视图设置动画?
【发布时间】:2021-04-13 20:19:00
【问题描述】:

我有一个要求,即视图需要位于底部的中心并根据其内容调整高度。所以在根constraint layout 内创建了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>
  • 如果我需要使用constraintSet,如何重组我的布局(没有嵌套组)?
  • 还有其他方法可以实现吗?我觉得constraintSet 使用起来非常简单。

尝试调用这个动画约束集,它将嵌套约束作为参数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);
    }

布局:

【问题讨论】:

  • 到目前为止您尝试过什么? ContraintSet 及其动画有什么问题?因为它工作得很好。
  • @GensaGames 我已经更新了上面的动画 sn-p。调用动画函数没有变化。
  • 如果您希望我们为您提供帮助,您应该提供一个可重现的示例来说明您拥有的东西,以及您想要实现的图像/视频之类的东西。我已经复制了你的 XML,但在我的设备上显示不好,看起来还缺少其他东西。
  • ConstraintLayout 是非常先进的,即使您在动画方面走得更远,然后 MotionLayoutConstraintLayout 与 Adob​​e After Effects 相似的动画师,您可以轻松地创建任何类型的动画。但是,我不明白你想做什么动画?
  • 啊,很简单。等待 10 分钟。

标签: android android-animation android-constraintlayout


【解决方案1】:

请记住,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">

然后,将约束创建为

//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)

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

constraintSet.clear(error_layout.id, ConstraintSet.BOTTOM)
constraintSet.connect(error_layout.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)

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) {
    }
})

把它放在beginDelayedTransition()之前。

【讨论】:

  • 谢谢伙计!它工作正常,感谢您的时间!实际上,我是 android 新手,不知道程序的变化。
  • 我们如何知道过渡何时结束?我想将可见性设置为GONE
  • @Balasubramanian 我已经添加了监听器,你可以检查一下。您可以使用onTransitionEnd() 在过渡结束时获取回调。
【解决方案2】:

我认为最简单的方法是使用转换管理器。

类似的东西

 findViewById(R.id.button).setOnClickListener {
        TransitionManager.beginDelayedTransition(constraintLayout)
        val constraint = if (changed) constraintSet1 else constraintSet2
        constraint.applyTo(constraintLayout)

附: - 哦,我看到有人已经说过同样的事情并且有更好的解释。

【讨论】:

  • constraintSet1constraintSet2 是什么?你能定义更好地理解吗?
  • @Balasubramanian 正如您在我的回答中看到的那样,我已将constraintSet 声明为val constraintSet = ConstraintSet(),然后我将布局的约束更改为动画。就这样,这两个constraintSet1constraintSet是两个预先声明的ConstraintSet,一个用于动画的第一阶段,一个用于第二阶段。没有什么新鲜的,没有什么令人困惑的。并且因为 ConstraintSet 仅在您调用 applyTo() 时应用,所以您可以在动画之前创建两个不同的 ConstraintSet 并可以像这个答案一样使用它们。
猜你喜欢
  • 2017-09-14
  • 1970-01-01
  • 2017-01-26
  • 1970-01-01
  • 2013-12-04
  • 2019-05-13
  • 1970-01-01
  • 2014-03-24
  • 1970-01-01
相关资源
最近更新 更多