Jetpack Compose:如何实现带动画的多选项悬浮操作按钮?
实现目标多选项悬浮操作按钮(FAB)动画效果
我想要实现带有如下动画效果的多选项悬浮操作按钮(FAB):
目前已完成多选项FAB的基础搭建,但无法实现目标动画效果,当前实现效果如下:
以下是修改后的完整代码,可实现目标动画:
修改后的FilterFabMenu
@Composable fun FilterFabMenu( visible: Boolean, items: List<FilterFabMenuItem>, modifier: Modifier = Modifier ) { Column( modifier = modifier.fillMaxWidth(), horizontalAlignment = Alignment.End, verticalArrangement = Arrangement.spacedBy(16.dp), ) { items.forEachIndexed { index, menuItem -> // 每个菜单项递增延迟,实现依次弹出/收起 val enterDelay = index * 50 val exitDelay = (items.size - 1 - index) * 50 AnimatedVisibility( visible = visible, enter = slideInVertically( initialOffsetY = { it }, animationSpec = tween(200, delayMillis = enterDelay, easing = FastOutSlowInEasing) ) + fadeIn( animationSpec = tween(200, delayMillis = enterDelay, easing = FastOutSlowInEasing) ) + scaleIn( initialScale = 0.8f, animationSpec = tween(200, delayMillis = enterDelay, easing = FastOutSlowInEasing) ), exit = slideOutVertically( targetOffsetY = { it }, animationSpec = tween(200, delayMillis = exitDelay, easing = FastOutSlowInEasing) ) + fadeOut( animationSpec = tween(200, delayMillis = exitDelay, easing = FastOutSlowInEasing) ) + scaleOut( targetScale = 0.8f, animationSpec = tween(200, delayMillis = exitDelay, easing = FastOutSlowInEasing) ) ) { FilterFabMenuItem( menuItem = menuItem, onMenuItemClick = {} ) } } } }
修改后的FilterView
@Composable fun FilterView( items: List<FilterFabMenuItem>, modifier: Modifier = Modifier ) { var filterFabState by rememberSaveable { mutableStateOf(FilterFabState.COLLAPSED) } val transition = updateTransition(targetState = filterFabState, label = "fab_transition") val iconRotationDegree by transition.animateFloat( transitionSpec = { tween(durationMillis = 200, easing = FastOutSlowInEasing) }, label = "rotation" ) { state -> if (state == FilterFabState.EXPANDED) 230f else 0f } Column( modifier = modifier.fillMaxSize().padding(16.dp), horizontalAlignment = Alignment.End, verticalArrangement = Arrangement.spacedBy(16.dp, Alignment.Bottom) ) { FilterFabMenu(items = items, visible = filterFabState == FilterFabState.EXPANDED) FilterFab( state = filterFabState, rotation = iconRotationDegree, onClick = { newState -> filterFabState = newState } ) } }
关键改动说明
- 逐个菜单项动画:将
AnimatedVisibility从整个Column移至每个FilterFabMenuItem外层,通过索引计算延迟,实现菜单从上到下依次弹出、从下到上依次收起的递进效果 - 动画组合优化:使用滑动+缩放+透明度的组合动画,替代原来的整体展开/收起,匹配目标效果的细腻过渡
- 状态绑定修复:简化
updateTransition的使用,直接关联filterFabState,确保主FAB的旋转动画与菜单状态完全同步 - 动画参数调整:设置200ms动画时长、50ms项级延迟,让动画过渡更自然流畅
内容的提问来源于stack exchange,提问作者Jarnojr
相关产品推荐
相关产品推荐

