Jetpack Compose:animateDp隐藏时下滑动画不生效问题
问题分析
当前弹窗隐藏时仅淡出无下滑动画的核心原因:你用AnimatedVisibility包裹了Dialog组件,当visibility变为false时,AnimatedVisibility的fadeOut退出动画会优先将Dialog从布局中移除,导致translateY的位移动画还未执行完成就被销毁,自然看不到下滑效果。
解决方案
移除AnimatedVisibility,改用updateTransition同时控制背景透明度与Card位移动画,确保动画完整执行后再关闭弹窗。修改后的代码如下:
@OptIn(ExperimentalComposeUiApi::class) @Composable fun DialogBottomSheets( isVisible: Boolean, onDismiss: () -> Unit, content: @Composable () -> Unit, modifier: Modifier = Modifier ) { val mutableInteractionSource = MutableInteractionSource() val screenHeight = rememberWindowInfo().screenHeight // 用updateTransition统一管理显示/隐藏状态与动画 val transition = updateTransition(targetState = isVisible, label = "BottomSheetTransition") // 背景透明度动画:显示时半透明,隐藏时完全透明 val backgroundAlpha by transition.animateFloat( transitionSpec = { tween(200) }, label = "BackgroundAlpha" ) { visible -> if (visible) 0.5f else 0f } // Card位移动画:显示时在底部,隐藏时滑出屏幕 val translateY by transition.animateDp( transitionSpec = { tween(200) }, label = "CardTranslateY" ) { visible -> if (visible) 0.dp else screenHeight } // 监听动画结束:从显示转隐藏时,等动画跑完再执行关闭回调 LaunchedEffect(transition.currentState, transition.targetState) { if (transition.currentState && !transition.targetState) { transition.awaitTransitionComplete() onDismiss() } } // 弹窗显示逻辑:目标状态为显示,或正在执行隐藏动画时,保持Dialog存在 if (isVisible || transition.currentState) { Dialog( onDismissRequest = { onDismiss() }, properties = DialogProperties( usePlatformDefaultWidth = false, dismissOnBackPress = true, dismissOnClickOutside = true ), ) { Box( modifier = Modifier .fillMaxSize() .background(color = Color.Black.copy(alpha = backgroundAlpha)) .clickable( interactionSource = mutableInteractionSource, indication = null ) { onDismiss() }, contentAlignment = Alignment.BottomCenter ) { Card( modifier = Modifier .fillMaxWidth() .wrapContentHeight() .offset(y = translateY) .clickable( interactionSource = mutableInteractionSource, indication = null ) {}, // 阻止点击Card内部触发关闭 backgroundColor = Color.White, shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) ) { content() } } } } }
关键修改说明
- 移除AnimatedVisibility:避免弹窗在动画中途被移除,保证位移动画完整执行。
- 双动画同步控制:用
updateTransition同时驱动背景透明度和Card位移,实现显示时上滑+背景淡入、隐藏时下滑+背景淡出的同步效果。 - 动画结束监听:通过
LaunchedEffect等待隐藏动画完成后再调用onDismiss,确保视觉效果完整。 - 点击事件处理:给Card添加空的
clickable阻止事件透传,实现点击弹窗外部才关闭的需求。
内容的提问来源于stack exchange,提问作者harish Padmanabh
相关产品推荐
相关产品推荐

