Flutter中如何实现点击按钮后从底部上浮的页面转场?
实现Flutter页面从底部向上浮起的效果
你要的这种从底部浮起覆盖整个页面的效果,确实和showModalBottomSheet这类弹窗组件不一样——后者是在当前页面之上弹出底部面板,而你需要的是页面级过渡动画或当前页面内全屏组件的滑入效果,下面给你两种针对性实现方案:
方案一:自定义页面路由(页面跳转场景)
如果是点击按钮跳转到新页面时需要这个浮起效果,可以自定义PageRoute替换系统默认路由过渡:
class SlideUpRoute extends PageRouteBuilder { final Widget page; SlideUpRoute({required this.page}) : super( pageBuilder: (context, animation, secondaryAnimation) => page, transitionDuration: const Duration(milliseconds: 300), transitionsBuilder: (context, animation, secondaryAnimation, child) { // 从底部向上滑动的位移动画 final slideTween = Tween<Offset>( begin: const Offset(0, 1), end: Offset.zero, ).animate(CurvedAnimation( parent: animation, curve: Curves.easeOutCubic, )); // 配合透明度动画增强浮起质感 final fadeTween = Tween<double>( begin: 0.6, end: 1.0, ).animate(animation); return FadeTransition( opacity: fadeTween, child: SlideTransition( position: slideTween, child: child, ), ); }, ); }
使用时直接通过这个路由跳转:
ElevatedButton( onPressed: () { Navigator.push( context, SlideUpRoute(page: const TargetPage()), ); }, child: const Text('打开浮起页面'), )
方案二:Stack + AnimatedContainer(当前页面内浮起场景)
如果不需要跳转页面,只是在当前页面内让全屏组件从底部浮起,用Stack嵌套AnimatedContainer就能实现:
class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { bool _isPanelVisible = false; @override Widget build(BuildContext context) { final screenHeight = MediaQuery.of(context).size.height; return Scaffold( body: Stack( children: [ // 原页面内容 Center( child: ElevatedButton( onPressed: () { setState(() { _isPanelVisible = !_isPanelVisible; }); }, child: const Text('触发浮起效果'), ), ), // 浮起的全屏面板 AnimatedContainer( duration: const Duration(milliseconds: 300), curve: Curves.easeOutCubic, transform: Matrix4.translationValues( 0, _isPanelVisible ? 0 : screenHeight, 0, ), child: Container( width: double.infinity, height: double.infinity, color: Colors.white, child: const Center( child: Text('浮起的页面内容'), ), ), ), ], ), ); } }
两种方案核心都是通过动画控制位置:从屏幕底部(Offset(0,1)或screenHeight)过渡到屏幕顶部,配合Curves.easeOutCubic这类缓动曲线,能让动画更接近你要的自然浮起效果。
内容的提问来源于stack exchange,提问作者dglee
相关产品推荐
相关产品推荐

