Flutter中通过generateRoute校验文件大小并弹出Dialog的实现问题
你这段代码里直接在generateRoute里弹Dialog不生效,核心原因是这里的context还没和当前页面的导航栈完成绑定,而且直接break返回null会终止路由跳转,但Dialog也没法正确渲染出来。下面给你两种可行的解决方案:
方法一:用临时透明页面中转(推荐)
当文件过大时,返回一个临时的空页面,在这个页面初始化完成后弹出Dialog,Dialog关闭后自动回到原页面,视觉上就像没跳转只弹了警告:
Route<dynamic>? generateRoute(RouteSettings settings, BuildContext context) { switch (settings.name) { case homePage: return MaterialPageRoute(builder: (context) => const HomePage()); case previewFilePage: var file = settings.arguments as FileModel; if (file.size > kMaxFileBytes) { // 返回临时空页面用于触发Dialog return MaterialPageRoute(builder: (context) { // 等待页面渲染完成后执行弹框逻辑 WidgetsBinding.instance.addPostFrameCallback((_) { showDialog( context: context, builder: (_) => PopUpDialogue( message: Text("File is too large"), ), ).then((_) { // 关闭Dialog后,回到原页面 Navigator.pop(context); }); }); // 透明空容器,不影响原页面显示 return SizedBox.shrink(); }); } else { return MaterialPageRoute( builder: (context) => PreviewFilePage( file: file, ), ); } default: return MaterialPageRoute(builder: (context) => const HomePage()); } }
方法二:统一封装跳转入口
既然有多个入口,不如直接封装一个全局跳转方法,所有地方都调用这个方法,彻底避免在路由生成器里处理弹窗逻辑:
void navigateToPreviewFile(BuildContext context, FileModel file) { if (file.size > kMaxFileBytes) { showDialog( context: context, builder: (_) => PopUpDialogue(message: Text("File is too large")), ); return; } Navigator.pushNamed(context, previewFilePage, arguments: file); }
之后所有需要跳转到PreviewFilePage的入口,都调用这个navigateToPreviewFile方法即可,不用每个入口单独写校验逻辑,弹窗也能正常显示在当前页面。
不用每个入口手动添加错误提示,上面两种方法都能实现统一处理的需求,完全符合你想用Dialog而不是错误页的偏好。
内容的提问来源于stack exchange,提问作者Davinci Cake
相关产品推荐
相关产品推荐

