【问题标题】:How to chain MotionLayout animation如何链接 MotionLayout 动画
【发布时间】:2020-01-07 10:23:53
【问题描述】:

我的任务是动画按钮从“离开”屏幕,首先到屏幕中心,然后到顶部(参见附件 xml 和屏幕截图)。所以基本上,我必须“链接”2个动画。我的问题是: 我怎样才能只使用 1 个转换?

我使用Transition.TransitionListener 实现了它,使用了doOnEnd() ktx 函数。它工作正常,但代码可能很复杂,因为我还计划删除 onDestroy() 中的侦听器以防止内存泄漏。

这是默认布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="?attr/actionBarSize">

    <View
        android:id="@+id/view"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/cardview_dark_background"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Text"
        app:layout_constraintTop_toBottomOf="@+id/view"
        app:layout_constraintStart_toEndOf="parent"
        />

</androidx.constraintlayout.motion.widget.MotionLayout>

这是第一个动画的结果:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="?attr/actionBarSize">

    <View
        android:id="@+id/view"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/cardview_dark_background"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Text"
        app:layout_constraintTop_toBottomOf="@+id/view"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        />

</androidx.constraintlayout.motion.widget.MotionLayout>

这是第二个动画的结果:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="?attr/actionBarSize">

    <View
        android:id="@+id/view"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/cardview_dark_background"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Text"
        app:layout_constraintTop_toBottomOf="@+id/view"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        />

</androidx.constraintlayout.motion.widget.MotionLayout>

活动:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Handler().postDelayed({
            val transitionPhase1 = transitionPhase1()
            transitionPhase1.doOnEnd {
                TransitionManager.beginDelayedTransition(root, transitionPhase2())
            }
            TransitionManager.beginDelayedTransition(root, transitionPhase1)
        }, 2000)
    }

    private fun transitionPhase1(): Transition {
        val constraintSet = ConstraintSet()
        constraintSet.clone(this, R.layout.activity_main_phase_1)
        constraintSet.applyTo(root)
        return AutoTransition()
    }

    private fun transitionPhase2(): Transition {
        val constraintSet = ConstraintSet()
        constraintSet.clone(this, R.layout.activity_main_phase_2)
        constraintSet.applyTo(root)
        return AutoTransition()
    }
}

我希望只有 1 个 TransitionManger.beginDelayedTransition() 方法调用。

【问题讨论】:

  • 是什么触发了这个动画?滚动?
  • 在上面提供的代码中,它会在 2 秒延迟后启动。但是我必须将此转换移植到另一个项目,那里的转换是由 http 请求响应触发的。
  • 你不能对这种动画使用运动布局,老实说你根本没有使用运动布局,你只是使用了motionlayout标签。 Please read here

标签: android-constraintlayout android-transitions android-motionlayout


【解决方案1】:

我建议您不要“链接两个过渡”,而是使用一个带有关键帧的过渡来解决这两个动作。这正是 &lt;KeyFrame&gt; 的用途。

为此,我建议创建一个 scene.xml 文件来处理约束集和转换。

然后您将只有 start 和 end 作为 constraintSet 以及您设置的中间状态作为关键帧。

如果您需要有关如何设置的示例,请告诉我。

【讨论】:

  • 你能举个例子吗
【解决方案2】:

您可以像我在下面所做的那样链接:

GitHub

<Transition
    android:id="@+id/startToEnd_materialCardView_email"
    app:constraintSetEnd="@+id/end_materialCardView_email"
    app:constraintSetStart="@+id/start_materialCardView_email"
    app:duration="500">
    <OnClick
        app:clickAction="toggle"
        app:targetId="@+id/start_materialCardView_email" />
</Transition>
<Transition
    android:id="@+id/endToStart_materialCardView_email"
    app:constraintSetEnd="@+id/start_materialCardView_email"
    app:constraintSetStart="@+id/end_materialCardView_email"
    app:duration="500">
    <OnClick
        app:clickAction="toggle"
        app:targetId="@+id/end_materialCardView_email" />
</Transition>

<Transition
    android:id="@+id/startToEnd_materialCardView_password"
    app:constraintSetEnd="@+id/end_materialCardView_password"
    app:constraintSetStart="@+id/end_materialCardView_email"
    app:duration="500">
    <OnClick
        app:clickAction="toggle"
        app:targetId="@+id/start_materialCardView_password" />
</Transition>
<Transition
    android:id="@+id/endToStart_materialCardView_password"
    app:constraintSetEnd="@+id/end_materialCardView_email"
    app:constraintSetStart="@+id/end_materialCardView_password"
    app:duration="500">
    <OnClick
        app:clickAction="toggle"
        app:targetId="@+id/end_materialCardView_password" />
</Transition>

<Transition
    android:id="@+id/startToEnd_materialCardView_birthDate"
    app:constraintSetEnd="@+id/end_materialCardView_birthDate"
    app:constraintSetStart="@+id/end_materialCardView_password"
    app:duration="500">
    <OnClick
        app:clickAction="toggle"
        app:targetId="@+id/start_materialCardView_birthDate" />
</Transition>
<Transition
    android:id="@+id/endToStart_materialCardView_birthDate"
    app:constraintSetEnd="@+id/end_materialCardView_password"
    app:constraintSetStart="@+id/end_materialCardView_birthDate"
    app:duration="500">
    <OnClick
        app:clickAction="toggle"
        app:targetId="@+id/end_materialCardView_birthDate" />
</Transition>

<Transition
    android:id="@+id/startToEnd_materialCardView_phoneNumber"
    app:constraintSetEnd="@+id/end_materialCardView_phoneNumber"
    app:constraintSetStart="@+id/end_materialCardView_birthDate"
    app:duration="1000">
    <OnClick
        app:clickAction="toggle"
        app:targetId="@+id/materialCardView_phoneNumber" />
</Transition>

Inspire Coding

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    相关资源
    最近更新 更多