You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 12:20:27