在flutter中的同一个widget中使用Provider

Nag*_*fer 2 dart flutter

我已经在我的小部件中声明了 MultipleProviders ,我想通过将变量设置为 ThemeData Primary 样本来使用它来更改应用程序的颜色,但它给了我这个与provider相关的错误。我在其他小部件中使用过并且它正在工作。我想我收到此错误是因为我在同一个小部件中使用它,我该如何解决它?

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var u = Provider.of<prov>(context);
    return MultiProvider(
      providers: [ChangeNotifierProvider(create: (_)=>prov())],
      child: GetMaterialApp(
        theme: ThemeData(primarySwatch: u.col),
        title: 'Material App',
        home: f(),
      ),
    );

  }
} 
Run Code Online (Sandbox Code Playgroud)

这是错误

错误:无法在此 MyApp 小部件上方找到正确的提供程序

发生这种情况是因为您使用的提供商BuildContext不包括您选择的提供商。有以下几种常见场景:

  • 您在您的中添加了一个新的提供程序main.dart并执行了热重载。要修复,请执行热重启。

  • 您尝试阅读的提供商处于不同的路线。

    提供者是“有范围的”。因此,如果您在路由中插入提供程序,则其他路由将无法访问该提供程序。

  • 您使用的BuildContext是您正在尝试读取的提供程序的祖先。

    确保 MyApp 在您的 MultiProvider/Provider 下。当您创建提供程序并尝试立即读取它时,通常会发生这种情况。

    例如,代替:

    Widget build(BuildContext context) {
      return Provider<Example>(
        create: (_) => Example(),
        // Will throw a ProviderNotFoundError, because `context` is associated
        // to the widget that is the parent of `Provider<Example>`
        child: Text(context.watch<Example>()),
      ),
    }
    
    Run Code Online (Sandbox Code Playgroud)

    考虑builder像这样使用:

    Widget build(BuildContext context) {
      return Provider<Example>(
        create: (_) => Example(),
        // we use `builder` to obtain a new `BuildContext` that has access to the provider
        builder: (context) {
          // No longer throws
          return Text(context.watch<Example>()),
        }
      ),
    }
    
    Run Code Online (Sandbox Code Playgroud)

Vic*_*ele 6

您收到错误是因为context您使用的无权访问provider.

解决方案就像错误消息中所说的那样:您可以使用 abuilderchild不是provider. 这会创建一个新的context读取provider创建的新对象。

你应该改变你的build方法。

  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [ChangeNotifierProvider(create: (_)=>prove())],
    
      //From here is where you make the change
    
      builder: (context, child) {
      var u = Provider.of<prov>(context);
    
      return GetMaterialApp(
        theme: ThemeData(primarySwatch: u.col),
        title: 'Material App',
        home: f(),
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)