如何修改showModalBottomSheet默认过渡效果并实现自定义动画
showModalBottomSheet自定义过渡效果实现方案
核心实现逻辑
showModalBottomSheet 自带transitionBuilder参数,专门用于自定义入场/退场动画,你不需要额外重写路由的buildTransitions方法,直接在调用底部弹窗的时候配置该参数即可。
常用过渡效果实现示例
1. 从底部滑入效果(SlideTransition)
showModalBottomSheet( context: context, isScrollControlled: true, transitionBuilder: (context, animation, secondaryAnimation, child) { // 定义从底部(0,1)到原始位置(0,0)的偏移量变化 final tween = Tween<Offset>(begin: const Offset(0, 1), end: Offset.zero); // 搭配曲线动画调整动效节奏 final offsetAnimation = animation.drive(tween.chain(CurveTween(curve: Curves.easeOut))); return SlideTransition( position: offsetAnimation, child: child, ); }, builder: (context) { // 你的底部弹窗内容 return Container( height: 300, color: Colors.white, ); }, );
2. 淡入效果(FadeTransition)
showModalBottomSheet( context: context, transitionBuilder: (context, animation, secondaryAnimation, child) { // 定义透明度从0到1的变化 final opacityAnimation = animation.drive(Tween<double>(begin: 0, end: 1)); return FadeTransition( opacity: opacityAnimation, child: child, ); }, builder: (context) { // 弹窗内容 return Container(height: 300, color: Colors.white); }, );
3. 滑动+淡入组合效果
你也可以嵌套多个动画组件实现复合效果:
transitionBuilder: (context, animation, secondaryAnimation, child) { final offsetTween = Tween<Offset>(begin: const Offset(0, 0.5), end: Offset.zero); final opacityTween = Tween<double>(begin: 0, end: 1); return FadeTransition( opacity: animation.drive(opacityTween), child: SlideTransition( position: animation.drive(offsetTween.chain(CurveTween(curve: Curves.easeOutCubic))), child: child, ), ); }
你现有代码的调整方案
你之前写的FractionalTranslation的写法也可以直接使用,只要放到transitionBuilder里即可,注意直接使用参数里的animation对象即可,不需要自己维护额外的_animation实例:
transitionBuilder: (context, animation, secondaryAnimation, child) { final _offsetTween = Tween<Offset>(begin: const Offset(0, 1), end: Offset.zero); return Align( alignment: Alignment.bottomCenter, child: FractionalTranslation( translation: _offsetTween.evaluate(animation), child: child, ), ); }
动画参数调整说明
- 修改
Tween的begin值可以调整入场起始位置/透明度 - 嵌套
CurveTween可以修改动画的运动曲线,实现回弹、减速等不同效果 - 自定义动画时长可以通过包裹
Theme组件实现:
Theme( data: Theme.of(context).copyWith( bottomSheetTheme: BottomSheetThemeData( transitionDuration: const Duration(milliseconds: 500), ), ), child: showModalBottomSheet(/* 原有配置 */), );
内容的提问来源于stack exchange,提问作者codenoobforreal
相关产品推荐
相关产品推荐

