Flutter:路由返回后重新执行Future的可行方案咨询
Flutter 页面返回后重新执行异步请求的解决方案
问题描述
我希望Flutter在通过Navigator.push()跳转至SettingsBiometry页面,再滑动返回当前组件后,重新执行CustomerService.getCustomerInformation()这个Future。目前仅能想到重新调用initState()函数的方法,但这似乎并非合理方案,请问有什么可行的解决办法?
相关代码
初始化状态代码:
@override void initState() { super.initState(); setState(() { loading = true; }); CustomerService.getCustomerInformation().then((value) { setState(() { name = value['name']; loading = false; }); }); }
getCustomerInformation函数说明:该函数为static Future<dynamic>类型,调用HttpsCallable函数并返回JSON格式响应。
路由跳转代码:
settingsTile( Icons.settings_outlined, Colors.pink, 'Settings', () => { Navigator.push( context, MaterialPageRoute( builder: (context) { return const SettingsBiometry(); }, ), ) })
可行方案
1. 监听Navigator.push的返回值(最直接简单)
Navigator.push会返回一个Future,当从跳转后的页面返回时,这个Future会完成。我们可以利用这一点,在返回后重新执行获取用户信息的逻辑。
首先将获取用户信息的逻辑抽象为单独的方法,避免代码重复:
// 抽象获取用户信息的方法 Future<void> _fetchCustomerInfo() async { setState(() { loading = true; }); try { final value = await CustomerService.getCustomerInformation(); setState(() { name = value['name']; loading = false; }); } catch (e) { // 处理请求失败的情况,比如提示错误 setState(() { loading = false; }); } }
然后修改initState,调用这个方法:
@override void initState() { super.initState(); _fetchCustomerInfo(); }
最后修改路由跳转代码,在页面返回后重新调用_fetchCustomerInfo:
settingsTile( Icons.settings_outlined, Colors.pink, 'Settings', () async { // 等待页面返回 await Navigator.push( context, MaterialPageRoute( builder: (context) => const SettingsBiometry(), ), ); // 返回后重新获取用户信息 _fetchCustomerInfo(); })
2. 使用路由监听(适合全局或多页面监听场景)
如果需要在多个页面返回时都触发刷新,或者需要更灵活的路由监听,可以使用RouteObserver和RouteAware:
- 首先在全局注册
RouteObserver:
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>(); void main() { runApp(MaterialApp( navigatorObservers: [routeObserver], // 注册路由观察者 home: YourHomePage(), )); }
- 在当前页面混入
RouteAware,并监听路由状态:
class YourPage extends StatefulWidget { @override State<YourPage> createState() => _YourPageState(); } class _YourPageState extends State<YourPage> with RouteAware { @override void didChangeDependencies() { super.didChangeDependencies(); // 订阅路由观察者 routeObserver.subscribe(this, ModalRoute.of(context)! as PageRoute); } @override void dispose() { // 取消订阅 routeObserver.unsubscribe(this); super.dispose(); } @override void didPopNext() { // 当从子页面返回当前页面时触发 _fetchCustomerInfo(); } // 这里是之前抽象的_fetchCustomerInfo方法 Future<void> _fetchCustomerInfo() async { // ... 实现同上 } @override void initState() { super.initState(); _fetchCustomerInfo(); } @override Widget build(BuildContext context) { // ... 页面构建代码 } }
注意:不要手动调用initState
initState是Flutter框架管控的生命周期方法,手动调用会破坏组件生命周期的一致性,可能导致状态混乱、资源重复订阅等问题,绝对不建议这么做。
内容的提问来源于stack exchange,提问作者Shared User
相关产品推荐
相关产品推荐

