博文所用 Flutter SDK:2.2.3,Dart SDK:2.13.4,get: 4.3.8。
文章目录
- 一:问题描述
- 二:解决方案
- 三:源码分析之《如何解决 Dialog 弹窗二次跳转路由异常的问题》
- 四:源码分析之《为什么在页面中没有这个问题在 Dialog 弹窗中却有》
一:问题描述
之前偶然间发现的一个问题,特此记录下。
上架小米商店的时候,被反馈在用户首次进入应用时要有隐私协议的弹窗,然后就给加了一个,点击《用户协议》时也能正常跳转到相应的 Web 页,以为这样就大功告成了,如下图所示
自己偶然间在测试的时候,当我在弹窗首次弹出后,第一次点击链接可以正常跳转,退出 Web 页再次点击时却没有任何反应,这是为什么呢?
断点调试了下,发现了问题的根本所在。
二:解决方案
设置 Get.toNamed() 方法的属性 preventDuplicates 为 false 即可,如下代码所示
/// 跳转到《用户协议》网页
void _toAgreementPage() {
Get.toNamed(
AppRoutes.WEB,
arguments: WebModel(title: "《用户协议》", url: agreementUrl, isLocal: false),
preventDuplicates: false, // “防止重复”设置为 false
);
}
然后问题得到解决,这个不仅针对 Dialog,也适合 Snackbar、BottomSheet 等方式。
三:源码分析之《如何解决 Dialog 弹窗二次跳转路由异常的问题》
有些同学喜欢打破沙锅问到底,想知道问题是解决了,但是为什么呢?那咱就源码分析走起。
首先通过断点调试来看下 Get.toNamed() 方法的源码,如下图所示
由图可知,toNamed() 方法上方注释的意思是
- 默认情况下,GetX 会阻止跳转到已经进入的路由。
- 如果你想解除这个限制,设置属性 preventDuplicates 为 false 即可。
由断点的位置可知,此时 preventDuplicates 为 true,又能进入到此判断,说明 page == currentRoute 条件也成立,也就是说当前要跳转的是已经进入的路由。
方法返回了 null ,所以在 Dialog 中再次点击链接跳转 Web 页的时候没有任何的反应。
我们只需要设置 preventDuplicates 为 false,条件不成立了,自然进入到了后面的判断。
四:源码分析之《为什么在页面中没有这个问题在 Dialog 弹窗中却有》
一:当路由进栈时
我们先来看一个类 GetObserver
,该类继承自 NavigatorObserver
类,作用是监听页面跳转。像平常用到的 Toast 等也都会继承这个类, GetObserver
类的源码如下图所示
当我点击《用户协议》链接跳转到 Web 页的时候,由红色方框选中部分可知,只有 PageRoute 类型的才允许修改当前路由 current 字段的值,所以此时会更新。
这也是为什么从 Dialog 弹窗进入到新页面的时候没什么问题。
二:当路由出栈时
如下图所示
当我点击 Web 页的返回按钮退出当前页面时,由红色方框选中部分可知,只有 PageRoute 类型的才允许修改当前路由 current 字段的值,而我们是从 Dialog 弹窗进入的,上一个页面的类型是 GetDialogRoute,不满足更新 current 的条件。
所以虽然我们的确是退出了 Web 页,但此时 current 的值并没有被更新,还是 /web
,也就是眼睛看到的是弹窗,但程序认为你在 Web 页,这就造成了同个页面无法跳转的问题。
至此,关于在 Flutter 中使用 Get 插件在 Dialog 弹窗中不能二次跳转路由的问题,便介绍到这里。
最后放一张 get 对当前路由类型判断的类,如下图所示
由图可知
- Dialog 类型是 GetDialogRoute,继承自 PopupRoute。
- Snackbar 类型是 SnackRoute,继承自 OverlayRoute。
- BottomSheet 类型是 GetModalBottomSheetRoute,继承自 PopupRoute。
- Page 类型是GetPageRoute,继承自 PageRoute。
你的问题得到解决了吗?欢迎在评论区留言。