使用auto_route的AutoTabsScaffold时Bloc无法关闭的问题
解决AutoRoute底部标签栏切换时Bloc/Cubit不销毁的问题
问题原因
AutoTabsScaffold默认会缓存所有标签页的页面实例,导致页面内的BlocProvider不会被销毁,对应的Cubit也就一直存活。另外如果通过getIt注册Cubit时使用了单例模式,也会导致Cubit无法被正常销毁。
解决方案
1. 关闭页面全局缓存
修改AutoTabsScaffold的keepAlive参数为false,这样切换标签时非活跃页面会被销毁,BlocProvider和Cubit也会随之被销毁:
@RoutePage(name: 'TabBarRoute') class AutoTapBar extends StatelessWidget { const AutoTapBar({super.key}); @override Widget build(BuildContext context) { return AutoTabsScaffold( routes: const [ Page1Route(), Page2Route(), Page3Route(), ], keepAlive: false, // 新增:关闭全局缓存 bottomNavigationBuilder: (_, tabsRouter) { return BottomNavigationBar( currentIndex: tabsRouter.activeIndex, onTap: tabsRouter.setActiveIndex, items: const [ BottomNavigationBarItem( icon: Icon(Icons.home), label: 'Page1', ), BottomNavigationBarItem( icon: Icon(Icons.streetview), label: 'Page2', ), BottomNavigationBarItem( icon: Icon(Icons.account_circle), label: 'Page3', ), ], ); }, ); } }
2. 针对单个路由设置缓存策略
如果需要部分页面缓存、部分销毁,可以在路由配置里单独设置keepAlive,同时保持AutoTabsScaffold的keepAlive为true:
修改AppRouter代码:
@AutoRouterConfig() class AppRouter extends _$AppRouter { @override List<AutoRoute> get routes => [ AutoRoute( path: '/', page: AppWrapperRoute.page, initial: true, children: [ AutoRoute( path: 'tab', page: TabBarRoute.page, children: [ AutoRoute(path: 'page1', page: Page1Route.page, keepAlive: true), // 缓存Page1 AutoRoute(path: 'page2', page: Page2Route.page, keepAlive: false), // 不缓存Page2 AutoRoute(path: 'page3', page: ProfileRoute.page, keepAlive: false), // 不缓存Page3 ], ), ], ), ]; }
3. 确保Cubit的getIt注册为工厂模式
检查你的依赖注入配置,确保Page3ScreenCubit是工厂模式注册,而非单例:
// 正确的注册方式(工厂模式) getIt.registerFactory<Page3ScreenCubit>(() => Page3ScreenCubit()); // 错误的注册方式(单例会导致Cubit一直存活) // getIt.registerSingleton<Page3ScreenCubit>(Page3ScreenCubit());
工厂模式下,每次BlocProvider.create都会创建新的Cubit实例,当页面销毁时,BlocProvider会自动调用Cubit的close方法。
内容的提问来源于stack exchange,提问作者coke_85
相关产品推荐
相关产品推荐

