MotionScheme:不会动画也能先用对 · AndroidX 源码指南
AAndroidX 源码指南
M3E 设计系统
ANDROIDX / COMPOSE / MATERIAL 3

MotionScheme:不会动画也能先用对

用主题提供的运动规格理解空间变化与视觉效果,不必从手写动画开始。

先不用自己发明动画参数

MotionScheme 的作用,是给 Material 组件提供一组统一的 FiniteAnimationSpecMaterialExpressiveTheme 默认使用 MotionScheme.expressive(),组件内部可以读取 MaterialTheme.motionScheme

源码把规格分为两类、每类三个速度:

类别适合变化可用规格
Spatial位置、大小、边界和形状default / fast / slow spatial
Effects颜色、透明度等视觉效果default / fast / slow effects

standard 与 expressive

  • MotionScheme.standard():源码描述为适合基础、实用、频繁交互,运动感觉更线性。
  • MotionScheme.expressive():源码推荐用于突出元素与 hero interaction,强调更有表现力的运动。

如果你只是使用 M3 组件,先让组件消费主题 motion 即可,不需要先学会 Animatable。手写自己的状态动画时,再从主题取 spec:

val spec = MaterialTheme.motionScheme.fastSpatialSpec<Float>()

val scale by animateFloatAsState(
    targetValue = if (pressed) 0.96f else 1f,
    animationSpec = spec,
    label = "press scale",
)

这里的代码展示 API 连接方式;具体动效是否适合你的界面,仍要在设备上观察,并检查“减少动态效果”等可访问性需求。

什么时候用哪个

  • 按下反馈、短距离变化:先考虑 fastSpatialSpec()
  • 常规布局/形状状态切换:先考虑 defaultSpatialSpec()
  • 大范围或强调性转场:评估 slowSpatialSpec(),不要滥用。
  • 颜色或 alpha:对应使用 effects spec,避免拿 spatial spec 混用。

复制即用

从主题取运动规格,驱动自己的状态动画:

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue

@Composable
fun PressScale(pressed: Boolean) {
    val spec = MaterialTheme.motionScheme.fastSpatialSpec<Float>()

    val scale by animateFloatAsState(
        targetValue = if (pressed) 0.96f else 1f,
        animationSpec = spec,
        label = "press scale",
    )
    // 把 scale 传给 Modifier.scale(scale)
}

速查:

  • 按下反馈、短距离变化:fastSpatialSpec()
  • 常规布局/形状状态切换:defaultSpatialSpec()
  • 强调性转场:slowSpatialSpec()
  • 颜色、透明度:fastEffectsSpec() / defaultEffectsSpec()