到目前为止,我已经阅读了有关
MotionLayout
here(官方文档)的所有可用文档、可用的示例、非常复杂的示例 here 以及来自许多网站的其他示例。
到目前为止我没能做到的是如何一一播放/启动动画。
KeyPosition
和KeyAttribute
可能是答案,但我没有找到任何示例/文档来解释如何使用它们。
这是
MotionScene
布局:
<?xml version="1.0" encoding="utf-8"?>
<MotionScene
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto"
>
<Transition
motion:constraintSetStart="@+id/start"
motion:constraintSetEnd="@+id/end"
motion:duration="500">
</Transition>
<ConstraintSet android:id="@+id/start">
<Constraint
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintTop_toBottomOf="parent"
motion:layout_constraintLeft_toLeftOf="parent"
motion:layout_constraintRight_toRightOf="parent"
android:id="@+id/bottomText"
/>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintLeft_toLeftOf="parent"
motion:layout_constraintRight_toRightOf="parent"
android:id="@+id/bottomText"
/>
</ConstraintSet>
<ConstraintSet android:id="@+id/start1">
<Constraint
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toTopOf="parent"
android:id="@+id/arcView"
/>
</ConstraintSet>
<ConstraintSet android:id="@+id/end1">
<Constraint
android:layout_width="match_parent"
android:layout_height="0dp"
motion:layout_constraintHeight_percent=".8"
motion:layout_constraintTop_toTopOf="parent"
android:id="@+id/arcView"
/>
</ConstraintSet>
</MotionScene>
这就是我启动它的方式:(即使使用
autoTransition
,它也不会自动启动)
val motionContainer : MotionLayout = findViewById(R.id.motionContainer)
motionContainer.setTransition(R.id.start, R.id.end)
motionContainer.transitionToEnd()
上面的复杂示例使用
motionLayout.doOnEnd()
来开始下一个转换,但这不是一个可用的函数,我也没有在他的代码中找到它。当我检查更多时,doOnEnd()
是Animator()
的函数,但找不到它与MotionScene
/MotionLayout
的关系。
我认为通过下一个转换它会如下所示工作,但这也没有帮助。
val motionContainer : MotionLayout = findViewById(R.id.motionContainer)
motionContainer.setTransition(R.id.start, R.id.end)
motionContainer.transitionToEnd()
motionContainer.setTransition(R.id.start1, R.id.end1)
motionContainer.transitionToEnd()
那么,如何一一播放这些转场呢?
可以添加
motion:autoTransition="animateToEnd"
此代码运行后
trans2
将自动运行trans3
,将motion:constraintSetEnd
第一个转换设置为motion:constraintSetEnd
在第二个转换
setForm -> setQuiz -> setQuizReady
<Transition
android:id="@+id/trans2"
motion:constraintSetEnd="@+id/setQuiz"
motion:constraintSetStart="@id/setForm"
motion:duration="5000"
motion:pathMotionArc="none">
<KeyFrameSet>
</KeyFrameSet>
</Transition>
<Transition
motion:autoTransition="animateToEnd"
android:id="@+id/trans3"
motion:constraintSetEnd="@+id/setQuizReady"
motion:constraintSetStart="@id/setQuiz"
motion:duration="5000"
motion:pathMotionArc="none">
<KeyFrameSet>
</KeyFrameSet>
</Transition>
您可以使用KeyFrameSet来实现它。假设您想首先对 BottomText 进行动画处理,然后对 arcView 进行动画处理,并且持续时间相同,则应该是这样的:
<KeyFrameSet>
<KeyPosition
app:framePosition="50"
app:motionTarget="@id/bottomText"
app:keyPositionType="pathRelative"
app:percentX="1"/>
<KeyPosition
app:framePosition="50"
app:motionTarget="@id/arcView"
app:keyPositionType="pathRelative"
app:percentX="0"/>
</KeyFrameSet>
这意味着,我希望第一个视图(bottomText)在总动画持续时间的一半时完成其路径。我希望第二个视图 (arcView) 保持在同一位置,直到总动画持续时间的一半,换句话说,直到第一个视图完成动画。
如果您希望其中一个动画更快或更慢,请使用framePosition属性。
有关这些属性的更多说明,这里是官方文档。
假设您有 3 个约束集,即“开始”、“中间”和“结束”。 您应该使用 Motion:autoTransition="animateToEnd" 定义 3 个自动转换。这些是“开始到中间”、“中间到结束”和“结束到开始”过渡。也许你错过了 MotionLayout 的 autoTransition 功能。
<?xml version="1.0" encoding="utf-8"?>
<MotionScene
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetEnd="@+id/middle"
motion:constraintSetStart="@id/start"
motion:autoTransition="animateToEnd"
motion:duration="2000">
</Transition>
<Transition
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@id/middle"
motion:autoTransition="animateToEnd"
motion:duration="2000">
</Transition>
<Transition
motion:constraintSetEnd="@+id/start"
motion:constraintSetStart="@id/end"
motion:autoTransition="animateToEnd"
motion:duration="2000">
</Transition>
<ConstraintSet android:id="@+id/start">
...
</ConstraintSet>
<ConstraintSet android:id="@+id/middle">
...
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
..
</ConstraintSet>
</MotionScene>
我有一个循环轮播图像示例,有 2 个替代解决方案。您可以查看博客https://bbasoglu.medium.com/looping-image-carousel-animation-using-motion-layout-9caaab81d8ea.