Flutter 如何使用consumer包装小部件函数并设置它';使用提供程序的onPressed函数?

Flutter 如何使用consumer包装小部件函数并设置它';使用提供程序的onPressed函数?,flutter,flutter-provider,state-management,Flutter,Flutter Provider,State Management,我是新来的,我正在学习。我的应用程序是关于制作许多按钮,每个按钮都会改变应用程序ui中特定内容(应用程序栏、背景、抽屉等)的颜色。因此,为了简化代码,我应该制作一个按钮小部件,如下所示: Widget colorButton( Color c){ return RaisedButton( onPressed: (){}, color: c, ); } Consumer<bG_Vairables>(builder: (context, v, child){

我是新来的,我正在学习。我的应用程序是关于制作许多按钮,每个按钮都会改变应用程序ui中特定内容(应用程序栏、背景、抽屉等)的颜色。因此,为了简化代码,我应该制作一个按钮小部件,如下所示:

Widget colorButton( Color c){
  return RaisedButton(
    onPressed: (){},
    color: c,
  );
}
Consumer<bG_Vairables>(builder: (context, v, child){
                            return colorButton(Color.fromRGBO(240, 230, 255,1) , v.setBG(Color.fromRGBO(240, 230, 255,1)));
                          },
                        ),
Navigator.of(context).push(MaterialPageRoute(builder:(context)=>ColorButtonPage()))
但是我注意到,当我调用这个按钮来改变任何东西的颜色时,我不能指定onPressed函数。因此(我不知道这是最好的方法还是有其他方法)我将函数更改为:

Widget colorButton( Color c, Function f){
  return RaisedButton(
    onPressed: (){f();},
    color: c,
  );
}
然后,我传递了我在模型前面创建的模型的函数,如下所示:

class bG_Vairables extends ChangeNotifier{
  Color bG;
  Function setBG(Color c){
    bG = c;
    notifyListeners();
  }
}
我举这样一个例子:

Widget colorButton( Color c){
  return RaisedButton(
    onPressed: (){},
    color: c,
  );
}
Consumer<bG_Vairables>(builder: (context, v, child){
                            return colorButton(Color.fromRGBO(240, 230, 255,1) , v.setBG(Color.fromRGBO(240, 230, 255,1)));
                          },
                        ),
Navigator.of(context).push(MaterialPageRoute(builder:(context)=>ColorButtonPage()))
Consumer(构建器:(上下文、v、子对象){
返回颜色按钮(Color.fromRGBO(240230255,1),v.setBG(Color.fromRGBO(240230255,1));
},
),
但我得到了这个错误:

The following ProviderNotFoundException was thrown building Consumer<bG_Vairables>(dirty):
Error: Could not find the correct Provider<bG_Vairables> above this Consumer<bG_Vairables> Widget

This likely happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:

- The provider you are trying to read is in a different route.

  Providers are "scoped". So if you insert of provider inside a route, then
  other routes will not be able to access that provider.

- You used a `BuildContext` that is an ancestor of the provider you are trying to read.

  Make sure that Consumer<bG_Vairables> is under your MultiProvider/Provider<bG_Vairables>.
  This usually happen when you are creating a provider and trying to read it immediatly.

  For example, instead of:

  ```
  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>()),
    ),
  }
  ```

  consider using `builder` like so:

  ```
  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>()),
      }
    ),
  }
  ```

If none of these solutions work, consider asking for help on StackOverflow:
https://stackoverflow.com/questions/tagged/flutter

The relevant error-causing widget was: 
  Consumer<bG_Vairables> file:///C:/Users/Mu'men/AndroidStudioProjects/provider_project/lib/main.dart:46:18
When the exception was thrown, this was the stack: 
#0      Provider._inheritedElementOf (package:provider/src/provider.dart:269:7)
#1      Provider.of (package:provider/src/provider.dart:221:30)
#2      Consumer.buildWithChild (package:provider/src/consumer.dart:177:16)
#3      SingleChildStatelessWidget.build (package:nested/nested.dart:260:41)
#4      StatelessElement.build (package:flutter/src/widgets/framework.dart:4576:28)
...
以下ProviderNotFoundException在生成使用者时引发(脏):
错误:在此使用者小部件上方找不到正确的提供程序
发生这种情况的原因可能是您使用了不包含提供程序的“BuildContext”
由你选择。有几个常见的场景:
-您试图读取的提供程序位于不同的路径中。
提供者是“有范围的”。所以,如果在路由中插入一个提供者,那么
其他路由将无法访问该提供商。
-您使用了“BuildContext”,它是您试图读取的提供程序的祖先。
确保消费者在您的多供应商/提供商的管理下。
这通常发生在您创建提供者并尝试立即读取它时。
例如,而不是:
```
小部件构建(构建上下文){
返回提供者(
创建:()=>Example(),
//将抛出ProviderNotFoundError,因为'context'已关联
//指向作为“提供者”父级的小部件`
子:文本(context.watch()),
),
}
```
考虑使用“Builder”这样:
```
小部件构建(构建上下文){
返回提供者(
创建:()=>Example(),
//我们使用“builder”来获取一个新的“BuildContext”,它可以访问提供者
生成器:(上下文){
//不再投掷
返回文本(context.watch()),
}
),
}
```
如果这些解决方案都不起作用,请考虑在StAcExpLoad上寻求帮助:
https://stackoverflow.com/questions/tagged/flutter
导致错误的相关小部件是:
消费者file:///C:/Users/Mu“男性/男性研究项目/project/provider_project/lib/main.dart:46:18
引发异常时,这是堆栈:
#0提供程序。\u继承了elementof(包:Provider/src/Provider.dart:269:7)
#1 Provider.of(包:Provider/src/Provider.dart:221:30)
#2 Consumer.buildWithChild(包:provider/src/Consumer.dart:177:16)
#3 SingleChildStatelessWidget.build(包:嵌套/嵌套.dart:260:41)
#4.element.build(包:flatter/src/widgets/framework.dart:4576:28)
...

您必须将
ChangeNotifierProvider
添加到写入
colorButton()
的小部件祖先的某个位置

例如

当前,如果您访问colorButton()的StatefulWidget页面(将其命名为ColorButtonPage),如下所示:

Widget colorButton( Color c){
  return RaisedButton(
    onPressed: (){},
    color: c,
  );
}
Consumer<bG_Vairables>(builder: (context, v, child){
                            return colorButton(Color.fromRGBO(240, 230, 255,1) , v.setBG(Color.fromRGBO(240, 230, 255,1)));
                          },
                        ),
Navigator.of(context).push(MaterialPageRoute(builder:(context)=>ColorButtonPage()))
将其更改为:

Navigator.of(context).push(MaterialPageRoute(builder:(context)=>ChangeNotifierProvider(create:(context)=> bG_Vairables(), child: ColorButtonPage(), ),),)

通过这种方式,消费者将能够找到bG_Vairables对象。

您必须将
ChangeNotifierProvider
添加到写入
colorButton()

例如

当前,如果您访问colorButton()的StatefulWidget页面(将其命名为ColorButtonPage),如下所示:

Widget colorButton( Color c){
  return RaisedButton(
    onPressed: (){},
    color: c,
  );
}
Consumer<bG_Vairables>(builder: (context, v, child){
                            return colorButton(Color.fromRGBO(240, 230, 255,1) , v.setBG(Color.fromRGBO(240, 230, 255,1)));
                          },
                        ),
Navigator.of(context).push(MaterialPageRoute(builder:(context)=>ColorButtonPage()))
将其更改为:

Navigator.of(context).push(MaterialPageRoute(builder:(context)=>ChangeNotifierProvider(create:(context)=> bG_Vairables(), child: ColorButtonPage(), ),),)

这样,消费者将能够找到bG_Vairables对象。

您在哪里创建了ChangeNotifierProvider?消费者需要主目录树中上面的提供者,如下所示:
void main(){runApp(多提供者:[ChangeNotifierProvider(create:(context)=>appBarVairables()),ChangeNotifierProvider(create:(context)=>bG_Vairables(),],child:MaterialApp(home:MyApp(),),),;}
我能想到的唯一一件事是,消费者不是在build方法中构建的,而是在其他地方创建的(您说您创建了一个消费者实例),因此上下文实际上并不相同,您能否发布您如何在小部件中使用它?您在哪里创建了ChangeNotifierProvider?消费者需要主目录树中上面的提供者,如下所示:
void main(){runApp(多提供者:[ChangeNotifierProvider(create:(context)=>appBarVairables()),ChangeNotifierProvider(create:(context)=>bG_Vairables(),],child:MaterialApp(home:MyApp(),),),;}
我能想到的唯一一件事是,消费者不是在build方法中构建的,而是在其他地方创建的(你说你创建了一个消费者实例),因此上下文实际上并不相同,你能告诉我你是如何在小部件中使用它的吗?