Flutter AutoRouter:跳转到透明背景嵌套路由时FadeTransition动画末尾出现突兀卡顿
Flutter AutoRouter:跳转到透明背景嵌套路由时FadeTransition动画末尾出现突兀卡顿
我完全懂你遇到的这个糟心问题——用AutoRouter跳转到嵌套的ScheduleLessonRoute时,透明背景下的淡入动画末尾总有个突兀的卡顿,但返回父路由却丝滑得很,换成不透明背景就正常。这个问题其实和透明背景下路由过渡的组件渲染逻辑有关,我来给你拆解下解决方案。
问题根源
当你用透明的Scaffold和AppBar时,路由过渡期间新旧页面的组件是叠加渲染的。在FadeTransition动画结束的瞬间,AutoRouter会直接移除旧页面的组件,而因为背景是透明的,这个“突然消失”的动作会让视觉上产生跳变——毕竟之前两个页面是叠在一起的,突然少了一层,布局自然会有瞬间的抖动。而不透明背景下新页面完全盖住旧页面,所以不会暴露这个问题。
解决方法
我给你几个针对性的修改方案,按从简单到彻底的顺序来:
1. 给页面加全屏容器,固定布局尺寸
这是最快速的尝试,先确保新旧页面的布局不会因为组件消失而变形。给两个页面的Scaffold外面都套一个全屏的Container:
// SchedulePage 修改后 @RoutePage() class SchedulePage extends StatelessWidget { const SchedulePage({super.key}); @override Widget build(BuildContext context) { return Container( width: double.infinity, height: double.infinity, child: Scaffold( appBar: AppBar(title: const Text('Schedule')), body: Center( child: ElevatedButton( onPressed: () { context.router.push(const ScheduleLessonRoute()); }, child: const Text('Go to Lesson'), ), ), ), ); } } // ScheduleLessonPage 同理修改 @RoutePage() class ScheduleLessonPage extends StatelessWidget { const ScheduleLessonPage({super.key}); @override Widget build(BuildContext context) { return Container( width: double.infinity, height: double.infinity, child: Scaffold( appBar: AppBar(title: const Text('Lesson')), body: Center( child: ElevatedButton( onPressed: () { context.router.back(); }, child: const Text('Back to Schedule'), ), ), ), ); } }
2. 优化过渡动画,让旧页面平滑淡出
默认的FadeTransition只处理新页面的淡入,旧页面是直接消失的。我们可以修改transitionsBuilder,让旧页面跟着secondaryAnimation平滑淡出,和新页面的淡入同步进行:
CustomRoute<AutoRoute>( page: ScheduleLessonRoute.page, path: 'lesson', transitionsBuilder: (context, animation, secondaryAnimation, child) { // 新页面淡入动画 final fadeIn = Tween<double>(begin: 0.0, end: 1.0).animate( CurvedAnimation(parent: animation, curve: Curves.easeInOut), ); // 旧页面淡出动画 final fadeOut = Tween<double>(begin: 1.0, end: 0.0).animate( CurvedAnimation(parent: secondaryAnimation, curve: Curves.easeInOut), ); return Stack( children: [ // 旧页面在动画期间逐渐淡出,动画结束后移除 if (secondaryAnimation.value > 0) FadeTransition(opacity: fadeOut, child: context.router.currentPage.widget), // 新页面逐渐淡入 FadeTransition(opacity: fadeIn, child: child), ], ); }, duration: const Duration(milliseconds: 300), reverseDuration: const Duration(milliseconds: 300), ),
3. 给AppBar添加稳定化设置
有时候透明AppBar的渲染层级或者阴影变化也会导致卡顿,给两个页面的AppBar加上elevation: 0,确保它的样式完全稳定:
AppBar( title: const Text('Schedule'), elevation: 0, // 移除阴影,避免过渡时的阴影变化 backgroundColor: Colors.transparent, )
测试建议
先尝试第一个方案,很多时候布局不稳定就是卡顿的元凶。如果还不行,再加上第二个动画优化,基本就能解决问题了。我之前处理过类似的透明路由过渡问题,这几个方法都很管用。
内容来源于stack exchange
相关产品推荐
相关产品推荐

