Search code examples
android-motionlayout

MotionLayout motionInterpolator with cubic function


MotionLayout motionInterpolator = cubic(0.25,0,0,1), The transition from start to end is fast and then slow, and when transitioning from end to start, it becomes slow and then fast. How can you make the transition from start to end or from end to start, all faster and then slower?

<Transition
        android:id="@+id/start_to_half_open"
        motion:constraintSetEnd="@+id/half_open"
        motion:constraintSetStart="@id/start"
        motion:duration="500"
        motion:transitionDisable="false"
        motion:layoutDuringTransition="callMeasure"
        motion:motionInterpolator="cubic(0.25,0,0,1)">
        <KeyFrameSet>
            <KeyAttribute
                android:alpha="0"
                motion:framePosition="79"
                motion:motionTarget="@+id/top_bar" />
            <KeyPosition
                motion:framePosition="79"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/top_bar"
                motion:percentX="0"
                motion:percentY="0" />
            <KeyPosition
                motion:framePosition="80"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/top_bar"
                motion:percentX="1"
                motion:percentY="1" />
            <KeyAttribute
                android:alpha="0"
                motion:framePosition="80"
                motion:motionTarget="@+id/top_bar" />
            <KeyAttribute
                android:alpha="1"
                motion:framePosition="95"
                motion:motionTarget="@+id/top_bar" />
            <KeyPosition
                motion:framePosition="95"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/top_bar"
                motion:percentX="1"
                motion:percentY="1" />

            <KeyAttribute
                android:alpha="0"
                motion:framePosition="79"
                motion:motionTarget="@+id/iv_player_new_feature" />
            <KeyPosition
                motion:framePosition="79"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/iv_player_new_feature"
                motion:percentX="0"
                motion:percentY="0" />
            <KeyAttribute
                android:alpha="0"
                motion:framePosition="80"
                motion:motionTarget="@+id/iv_player_new_feature" />
            <KeyPosition
                motion:framePosition="80"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/iv_player_new_feature"
                motion:percentX="1"
                motion:percentY="1" />
            <KeyAttribute
                android:alpha="0"
                motion:framePosition="95"
                motion:motionTarget="@+id/iv_player_new_feature" />
            <KeyPosition
                motion:framePosition="95"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/iv_player_new_feature"
                motion:percentX="1"
                motion:percentY="1" />

            <KeyAttribute
                android:alpha="0"
                motion:framePosition="79"
                motion:motionTarget="@+id/iv_video_play_setting" />
            <KeyPosition
                motion:framePosition="79"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/iv_video_play_setting"
                motion:percentX="0"
                motion:percentY="0" />
            <KeyPosition
                motion:framePosition="80"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/iv_video_play_setting"
                motion:percentX="1"
                motion:percentY="1" />
            <KeyAttribute
                android:alpha="0"
                motion:framePosition="80"
                motion:motionTarget="@+id/iv_video_play_setting" />
            <KeyAttribute
                android:alpha="1"
                motion:framePosition="95"
                motion:motionTarget="@+id/iv_video_play_setting" />
            <KeyPosition
                motion:framePosition="95"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/iv_video_play_setting"
                motion:percentX="1"
                motion:percentY="1" />

        </KeyFrameSet>
    </Transition>



 <Transition
        android:id="@+id/half_open_to_start"
        motion:constraintSetEnd="@+id/start"
        motion:constraintSetStart="@id/half_open"
        motion:duration="500"
        motion:motionInterpolator="cubic(0.25,0,0,1)">
        <KeyFrameSet>
            <KeyAttribute
                android:alpha="0"
                motion:framePosition="79"
                motion:motionTarget="@+id/iv_video_play_setting" />
            <KeyPosition
                motion:framePosition="79"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/top_bar"
                motion:percentX="0"
                motion:percentY="0" />
            <KeyPosition
                motion:framePosition="80"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/top_bar"
                motion:percentX="1"
                motion:percentY="1" />
            <KeyAttribute
                android:alpha="0"
                motion:framePosition="80"
                motion:motionTarget="@+id/top_bar" />
            <KeyAttribute
                android:alpha="1"
                android:visibility="visible"
                motion:framePosition="95"
                motion:motionTarget="@+id/top_bar" />
            <KeyPosition
                motion:framePosition="95"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/top_bar"
                motion:percentX="1"
                motion:percentY="1" />

            <KeyAttribute
                android:alpha="0"
                motion:framePosition="79"
                motion:motionTarget="@+id/iv_player_new_feature" />
            <KeyPosition
                motion:framePosition="79"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/iv_player_new_feature"
                motion:percentX="0"
                motion:percentY="0" />
            <KeyAttribute
                android:visibility="visible"
                motion:framePosition="80"
                motion:motionTarget="@+id/iv_player_new_feature" />
            <KeyPosition
                motion:framePosition="80"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/iv_player_new_feature"
                motion:percentX="1"
                motion:percentY="1" />

            <KeyAttribute
                android:alpha="0"
                motion:framePosition="79"
                motion:motionTarget="@+id/iv_video_play_setting" />
            <KeyPosition
                motion:framePosition="79"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/iv_video_play_setting"
                motion:percentX="0"
                motion:percentY="0" />
            <KeyPosition
                motion:framePosition="80"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/iv_video_play_setting"
                motion:percentX="1"
                motion:percentY="1" />
            <KeyAttribute
                android:alpha="0"
                motion:framePosition="80"
                motion:motionTarget="@+id/iv_video_play_setting" />
            <KeyAttribute
                android:alpha="1"
                motion:framePosition="95"
                motion:motionTarget="@+id/iv_video_play_setting" />
            <KeyPosition
                motion:framePosition="95"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/iv_video_play_setting"
                motion:percentX="1"
                motion:percentY="1" />
        </KeyFrameSet>
    </Transition>

mMotionLayout.setTransition(R.id.half_open,R.id.start);

I have tried, if it is the start state, then set the corresponding transsion, if the end state sets another transsion, the difference between the two transsions is that start and end are reversed. Doing so solves the problem if only two states are switched, and each time the start state starts. But I've been adapting to folding screens recently, so the starting state may be end, which leads to a lot of animation, such as repeated execution. Looking at the source code, I found that setTranssion itself executed transsionToEnd, which was not what I wanted.


Solution

  • Two way you can do this.

    1. Use an ObjectAnimator to drive the setProgress method.
    2. Before Transitioning get the transition and reverse it. cubic(0.25,0,0,1) -> cubic(1,0,0,0.25)

    You will still have a problem of what happens if you are in mid transitions and need to change directions.