Play animation sequentially - Motion Layout

Viewed 1519

So far, I've read all the documentation available about MotionLayout here (the official docs), examples available on it, a very complex example here and other examples from many websites. What I failed to get so far is how to play/start the animations one by one.

The KeyPosition and KeyAttribute are possibly the answer but I didn't find any example/documentation explaining how can I utilise them.

This is the MotionScene layout:

<?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>

This is how I start it: (it doesn't start automatically even with the autoTransition)

val motionContainer : MotionLayout = findViewById(R.id.motionContainer)
motionContainer.setTransition(R.id.start, R.id.end)
motionContainer.transitionToEnd()

The complex example above uses motionLayout.doOnEnd() to start the next transition but that is not an available function, nor I found it anywhere in his code. As I checked more, doOnEnd() is a function of Animator() but no relation of it with MotionScene/MotionLayout could be found.

I thought by passing next transition it would work as shown below but that didn't help too.

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

So, how to play these transitions one by one?

2 Answers

You can realize it by using a KeyFrameSet. Assuming that you want to first animate bottomText and then arcView, with equal durations, it should be something like this:

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

This means, I want the first view (bottomText) to complete its path at the half of the total animation duration. And I want the second view (arcView) to stay at the same position until the half of the total animation duration, in other words, until the first view completes animating.

If you want one of them to be animated faster or slower, play with the framePosition attribute.

For more explanation on these attributes, here is the official doc.

You can add

motion:autoTransition="animateToEnd"

this code after run trans2 will auto run trans3, set motion:constraintSetEnd first transition to motion:constraintSetEnd at second transition

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>
Related