我有一个简单的提供程序类:-
class DataProvider with ChangeNotifier {
int count;
void updateCount() {
count = count + 1;
notifyListeners();
}
}
我正在将此提供程序附加到以下课程:-
class MyWidget extends StatelessWidget{
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => DataProvider(),
child: Scaffold(
body: raisedButton(
onPressed: () {
Provider.of<DataProvider>(context).updateCount();
}
child: Text("Click!")
),
),
),
}
及其以下错误:-
I/flutter (32011): Error: Could not find the correct Provider<DataProvider> above this MyWidget
Widget
I/flutter (32011): To fix, please:
I/flutter (32011): * Ensure the Provider<DataProvider> is an ancestor to this MyWidget Widget
I/flutter (32011): * Provide types to Provider<DataProvider>
I/flutter (32011): * Provide types to Consumer<DataProvider>
I/flutter (32011): * Provide types to Provider.of<DataProvider>()
I/flutter (32011): * Ensure the correct `context` is being used.
这可能是什么原因?
修改:-
当我从定义的窗口小部件的任何子窗口小部件访问提供程序时,它工作正常。 ChangeNotifierProvider
。
答案 0 :(得分:1)
您需要将raisedButton
包裹在Consumer
中。
Consumer小部件有两个主要用途:
它允许我们在没有供应商的情况下从提供商那里获得价值 BuildContext是所述提供程序的后代,因此 无法使用Provider.of。这种情况通常发生在 创建提供程序的小部件也是其消费者之一,例如 以下示例:
@override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (_) => Foo(), child: Text(Provider.of<Foo>(context).value), ); }
此示例将引发ProviderNotFoundException,因为 使用BuildContext调用Provider.of,该BuildContext是 提供者。
相反,我们可以使用Consumer小部件,它将调用Provider.of 拥有自己的BuildContext。
使用Consumer,前面的示例将变为:
@override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (_) => Foo(), child: Consumer<Foo>( builder: (_, foo, __) => Text(foo.value), }, ); }
这不会引发ProviderNotFoundException并将正确构建 文本。每当foo值更改时,它还将更新Text。
请参阅:https://pub.dev/documentation/provider/latest/provider/Consumer-class.html
答案 1 :(得分:1)
这是因为您使用错误的Provider.of<DataProvider>(context).updateCount()
来呼叫context
。您正在使用context
方法提供的build
,该方法在层次结构中比您尝试访问的提供者要高。您需要使用属于提供者的后代(在层次结构中较低)的context
。
将Scaffold
包装在Builder
小部件中,这将在小部件层次结构中的该级别上显示一个新的context
,并使用该上下文。
您也可以使用Consumer
,尽管在您的示例中它不是最佳选择,因为每次在Provider中调用Consumer
时,notifyListeners()
都会重新生成,这将是多余的,因为您的用户界面不会改变。
答案 2 :(得分:0)
Builder小部件内有脚手架有助于我解决提供程序的问题
Widget build(BuildContext context) {
return ChangeNotifierProvider<StatusViewModel>(
create: (context) => StatusViewModel(),
child: Builder(
builder: (context){
return Scaffold(
appBar: AppBar(
title: Text("this is appbar"),
),
);
},
),
);}