Flutter弹窗关闭后返回带必传参数的上一级页面实现方法
问题描述
我开发了一款Flutter应用,用户点击已配对蓝牙设备列表中的设备名称,即可与对应设备建立蓝牙连接,相关实现代码如下:
final BluetoothDevice server; DataCollectionPage({required this.server}); // 省略部分无关代码 // ............................................................................... child: ListView( children: devices .map((_device)=> BluetoothDeviceListEntry( device: _device, enabled: true, onTap: (){ if (kDebugMode) { print("item"); } _startDataCollection(context, _device); }, // 省略部分无关代码 // ................................................................................ void _startDataCollection(BuildContext context, BluetoothDevice server){ Navigator.of(context).push(MaterialPageRoute(builder: (context){ return DataCollectionPage(server: server); })); }
导航跳转至 DataCollectionPage 页面后,我会在该页面执行相关操作与数据采集逻辑,流程结束后将跳转至名为 DataCollectionTimer 的页面。该页面会在屏幕上展示数秒倒计时,倒计时结束后弹出提示对话框,我希望点击对话框的关闭按钮时,直接返回至之前的 DataCollectionPage 页面。
如果尝试使用如下代码重新跳转构建DataCollectionPage:
MaterialPageRoute( builder: (context) => DataCollectionPage(), ),
会抛出参数缺失错误,因为DataCollectionPage要求必传server参数,而该参数是从其他类的已配对设备列表中获取的。
需要实现:从当前页面直接返回至已有的DataCollectionPage页面,无需一路回退到展示已配对设备列表的页面。
解决方案
不需要重新构建新的DataCollectionPage实例,直接使用Navigator的路由操作能力即可,根据你的跳转链路选对应实现:
- 常规场景:从
DataCollectionPage调用push跳转到DataCollectionTimer时,路由栈会自动保留之前的DataCollectionPage实例,完全不需要重新传递server参数。点击对话框关闭按钮时,依次弹出当前对话框、弹出Timer页面路由,就能直接回到栈中留存的原有DataCollectionPage,页面状态也会完整保留:
// 对话框关闭按钮点击回调 onPressed: () { Navigator.of(context).pop(); // 关闭弹出的提示对话框 Navigator.of(context).pop(); // 退出当前DataCollectionTimer页面,回到已有DataCollectionPage }
- 特殊场景:如果跳转
DataCollectionTimer时使用了pushReplacement替换了栈内的DataCollectionPage,就提前把server参数透传到DataCollectionTimer页面,返回时直接使用即可,不需要回退到设备列表页重新获取:- 先给
DataCollectionTimer添加必填的server属性:
final BluetoothDevice server; const DataCollectionTimer({super.key, required this.server});- 从
DataCollectionPage跳转Timer页面时把持有的server实例传入:
Navigator.of(context).push(MaterialPageRoute(builder: (context) { return DataCollectionTimer(server: server); }));- 关闭对话框返回时,直接用当前页持有的server实例构建
DataCollectionPage即可,不会触发参数缺失错误:
onPressed: () { Navigator.of(context).pop(); // 关闭提示对话框 Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) { return DataCollectionPage(server: server); })); } - 先给
优先选择第一种方案,无需重建页面,性能更好,
DataCollectionPage上已有的操作状态、蓝牙连接状态都不会丢失。
内容的提问来源于stack exchange,提问作者taha khamis
相关产品推荐
相关产品推荐

