Flutter从Provider Store取主色设主题时上下文作用域报错解决
问题分析
你这里的核心问题是:MaterialApp 所在层级无法直接获取 ChangeNotifierProvider 提供的 MyStore 实例——当前代码里的 context 属于 ChangeNotifierProvider.create 函数的上下文,其作用域不覆盖后续的 MaterialApp,自然找不到对应的 Provider。
解决方案
以下是几种可行的修复方式,按推荐程度排序:
方案1:使用 Consumer(推荐)
Consumer 是 Provider 生态的标准组件,既能获取正确的上下文,还能自动监听 MyStore 的变化,当用户修改主色时自动更新主题:
void main() { runApp( ChangeNotifierProvider( create: (context) => MyStore(), child: Consumer<MyStore>( builder: (context, store, child) { return MaterialApp( theme: primaryTheme(store.appColors.primaryColor), home: child!, ); }, // 将不需要重建的组件放在child参数里,提升性能 child: NavigationBarApp(), ), ) ); }
方案2:使用 Builder 组件
Builder 会提供一个位于 ChangeNotifierProvider 之下的新上下文,让你能正确获取到 MyStore:
void main() { runApp( ChangeNotifierProvider( create: (context) => MyStore(), child: Builder( builder: (context) { return MaterialApp( theme: primaryTheme(Provider.of<MyStore>(context).appColors.primaryColor), home: NavigationBarApp() ); }, ), ) ); }
注意:Provider.of 默认会监听 MyStore 的变化,所以颜色修改时主题会自动更新;如果不需要监听可以添加 listen: false 参数。
方案3:预初始化 MyStore(仅适用于不需要动态更新的场景)
如果你的主题不需要随用户修改颜色实时更新,可以提前初始化 MyStore,再通过 ChangeNotifierProvider.value 传入:
void main() { final myStore = MyStore(); runApp( ChangeNotifierProvider.value( value: myStore, child: MaterialApp( theme: primaryTheme(myStore.appColors.primaryColor), home: NavigationBarApp() ), ) ); }
⚠️ 这个方法的缺陷是:用户修改颜色后,主题不会自动刷新,所以不满足你“可随时修改颜色”的需求,仅作参考。
内容的提问来源于stack exchange,提问作者HuLu ViCa
相关产品推荐
相关产品推荐

