Flutter中结合MultiProvider使用GetX导航失效问题排查
问题原因
你用Get.to直接将MultiProvider作为目标页面传入时,SavedArticlePage的上下文被嵌套在MultiProvider层级中,导致GetX导航无法正确关联当前页面的导航栈上下文,进而使得页面内部的跳转操作失效。而原生Navigator.push是基于传入的context直接查找导航器,所以能正常工作。
解决方案
方案1:将MultiProvider移至SavedArticlePage内部
修改SavedArticlePage的代码,把MultiProvider作为页面build方法的根widget:
class SavedArticlePage extends StatelessWidget { const SavedArticlePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { // 从当前上下文获取已有的languageModel和authenticationModel final languageModel = Provider.of<LanguageModel>(context, listen: false); final authenticationModel = Provider.of<AuthenticationModel>(context, listen: false); return MultiProvider( providers: [ ChangeNotifierProvider.value(value: languageModel), ChangeNotifierProvider.value(value: authenticationModel), ChangeNotifierProvider(create: (_) => SavedArticleModel()), ], child: Scaffold( // 原来的SavedArticlePage页面内容 appBar: AppBar(title: const Text("Saved Articles")), body: // ... ), ); } }
然后跳转时直接传入SavedArticlePage:
await Get.to(() => const SavedArticlePage());
方案2:结合GetX依赖注入管理Provider
提前注入SavedArticleModel,再简化MultiProvider的使用:
// 跳转前注入SavedArticleModel Get.put(SavedArticleModel()); // 执行跳转 await Get.to(() => const SavedArticlePage());
修改SavedArticlePage的build方法:
@override Widget build(BuildContext context) { final languageModel = Provider.of<LanguageModel>(context, listen: false); final authenticationModel = Provider.of<AuthenticationModel>(context, listen: false); final savedArticleModel = Get.find<SavedArticleModel>(); return MultiProvider( providers: [ ChangeNotifierProvider.value(value: languageModel), ChangeNotifierProvider.value(value: authenticationModel), ChangeNotifierProvider.value(value: savedArticleModel), ], child: // 页面内容 ); }
方案3:使用GetX的Binding机制(推荐)
创建一个Binding类来管理Provider的注入:
class SavedArticleBinding extends Bindings { @override void dependencies() { // 注入SavedArticleModel Get.put(SavedArticleModel()); // 如果languageModel和authenticationModel是全局的,这里可以不用重复注入,直接在页面中获取 } }
跳转时指定binding:
await Get.to(() => const SavedArticlePage(), binding: SavedArticleBinding());
然后SavedArticlePage内部的MultiProvider关联已有的实例:
@override Widget build(BuildContext context) { final languageModel = Provider.of<LanguageModel>(context, listen: false); final authenticationModel = Provider.of<AuthenticationModel>(context, listen: false); final savedArticleModel = Get.find<SavedArticleModel>(); return MultiProvider( providers: [ ChangeNotifierProvider.value(value: languageModel), ChangeNotifierProvider.value(value: authenticationModel), ChangeNotifierProvider.value(value: savedArticleModel), ], child: // 页面内容 ); }
内容的提问来源于stack exchange,提问作者Sebb
相关产品推荐
相关产品推荐

