You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让MotionLayout双向过渡均实现先快后慢的cubic插值效果?

MotionLayout双向动画均实现先快后慢的解决方案

问题描述

在MotionLayout中设置motionInterpolator="cubic(0.25,0,0,1)"后,start到half_open的正向过渡为先快后慢,但half_open到start的反向过渡却变为先慢后快。期望双向过渡都实现先快后慢的效果。

尝试过反转Transition的起止状态处理,但适配折叠屏场景时,初始状态可能为half_open,会导致动画重复执行;查看源码发现setTransition()方法本身会自动执行transitionToEnd,不符合需求。

相关Transition配置如下:

<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和KeyPosition配置 -->
    </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和KeyPosition配置 -->
    </KeyFrameSet>
</Transition>

代码调用:

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

解决方案

1. 为反向Transition配置对应先快后慢的插值器

MotionLayout默认会在反向播放时反转插值器的时间进度,导致曲线变为先慢后快。要让反向动画也保持先快后慢,需为half_open_to_start设置反向对应的贝塞尔曲线:
将该Transition的motionInterpolator改为cubic(0.25,1,0,0),此曲线会让反向动画从half_open到start时,一开始快速变化,随后逐渐减速,实现先快后慢的效果。

修改后的反向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,1,0,0)">
    <KeyFrameSet>
        <!-- 保留原有KeyAttribute和KeyPosition配置 -->
    </KeyFrameSet>
</Transition>

2. 使用setCurrentState设置初始状态,避免自动触发动画

setTransition()方法会自动触发向end状态的过渡,不符合折叠屏初始状态可能为half_open的需求。改用setCurrentState()设置初始状态,该方法仅切换状态而不触发动画:

// 根据折叠屏实际状态设置初始状态,例如此处初始为half_open
mMotionLayout.setCurrentState(R.id.half_open);

3. 禁用自动过渡,确保使用自定义双向Transition

在MotionScene根节点添加motion:autoTransition="none",禁止系统自动生成反向Transition,强制使用你定义的两个独立Transition:

<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto"
    motion:autoTransition="none">

    <!-- 你的ConstraintSet和Transition配置 -->
</MotionScene>

4. 手动触发过渡

需要切换状态时,使用transitionToState()方法,避免使用setTransition():

// 从half_open切换到start
mMotionLayout.transitionToState(R.id.start);
// 从start切换到half_open
mMotionLayout.transitionToState(R.id.half_open);

内容的提问来源于stack exchange,提问作者shallow light

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 15:07:04