使用InternetConnectionChecker监听网络恢复后导航至当前组件问题求助
解决网络恢复后导航回原页面的问题(InternetConnectionChecker)
我使用InternetConnectionChecker实现全局网络状态监听,断网时能正常显示NoInternet页面,但网络恢复后总是自动跳回HomePage,希望恢复后回到断网前的当前页面。当前代码如下:
GetMaterialApp( // initialBinding: DataBinding(), navigatorKey: NavigationService.navigatorKey, builder: (context , child){ return StreamBuilder<InternetConnectionStatus>( stream: InternetConnectionChecker().onStatusChange, builder: (context , snapshot){ final connectivityResult = snapshot.data; print("result"+connectivityResult.toString()); if(connectivityResult.toString()=="InternetConnectionStatus.disconnected") { return NoInternet(); } return child!; }, ); }, debugShowCheckedModeBanner: false, theme: Themes.light, home:HomePage(deviceAddress: ''));
// global context class class NavigationService { static GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); }
问题原因
当前代码的核心问题是:在GetMaterialApp的builder中,断网时直接返回NoInternet组件,这会完全替换掉原有的页面导航栈。当网络恢复后返回child,而child对应初始的HomePage子树,导致之前的页面栈丢失,只能回到首页。
解决方案
方案1:使用Overlay遮罩(推荐)
这种方式不会破坏原有导航栈,仅在当前页面顶层添加无网络遮罩,网络恢复后移除遮罩即可回到原页面,体验更流畅。
修改代码如下:
// 全局变量存储Overlay条目 OverlayEntry? _noInternetOverlay; GetMaterialApp( navigatorKey: NavigationService.navigatorKey, builder: (context, child) { return StreamBuilder<InternetConnectionStatus>( stream: InternetConnectionChecker().onStatusChange, initialData: InternetConnectionStatus.connected, // 设置初始连接状态 builder: (context, snapshot) { final connectivityResult = snapshot.data; if (connectivityResult == InternetConnectionStatus.disconnected) { // 未显示遮罩时创建并插入 _noInternetOverlay ??= OverlayEntry( builder: (context) => NoInternet(), ); if (!_noInternetOverlay!.mounted) { Overlay.of(context)?.insert(_noInternetOverlay!); } } else { // 网络恢复时移除遮罩 _noInternetOverlay?.remove(); _noInternetOverlay = null; } return child!; }, ); }, debugShowCheckedModeBanner: false, theme: Themes.light, home: HomePage(deviceAddress: ''), );
方案2:保存路由记录并恢复
如果需要保持页面切换的形式,可以在断网前记录当前路由,网络恢复时导航回该路由。
// 全局变量存储最后访问的路由 String? _lastRoute; GetMaterialApp( navigatorKey: NavigationService.navigatorKey, builder: (context, child) { return StreamBuilder<InternetConnectionStatus>( stream: InternetConnectionChecker().onStatusChange, initialData: InternetConnectionStatus.connected, builder: (context, snapshot) { final connectivityResult = snapshot.data; final currentRoute = NavigationService.navigatorKey.currentState?.currentRoute?.settings.name; if (connectivityResult == InternetConnectionStatus.disconnected) { // 排除NoInternet页面,避免重复记录 if (currentRoute != '/no-internet') { _lastRoute = currentRoute; } return NoInternet(); } else { // 网络恢复后导航回原路由 if (_lastRoute != null) { WidgetsBinding.instance.addPostFrameCallback((_) { Get.toNamed(_lastRoute!); _lastRoute = null; }); } return child!; } }, ); }, debugShowCheckedModeBanner: false, theme: Themes.light, home: HomePage(deviceAddress: ''), // 注册NoInternet页面路由 routes: { '/no-internet': (context) => NoInternet(), // 其他路由配置 }, );
方案对比
- 方案1无需处理路由逻辑,不会改变页面栈,用户体验更自然,优先推荐。
- 方案2需要维护路由记录,需注意避免重复导航、路由不存在等异常情况。
内容的提问来源于stack exchange,提问作者rasheed
相关产品推荐
相关产品推荐

