M3E 设计系统
ANDROIDX / COMPOSE / MATERIAL 3
MotionScheme:不会动画也能先用对
用主题提供的运动规格理解空间变化与视觉效果,不必从手写动画开始。
先不用自己发明动画参数
MotionScheme 的作用,是给 Material 组件提供一组统一的 FiniteAnimationSpec。MaterialExpressiveTheme 默认使用 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()