我有一个简单的提供程序类:-
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
。
您需要将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。
使用消费者,上一个示例将成为:
@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
这是因为您使用错误的Provider.of<DataProvider>(context).updateCount()
来调用context
。您正在使用context
方法提供的build
,该方法在层次结构中比您尝试访问的提供者要高。您需要使用属于提供者的后代(在层次结构中较低)的context
。
将Scaffold
包装在Builder
小部件中,这会在小部件层次结构中的该级别上显示一个新的context
,并改用该上下文。
您也可以使用Consumer
,尽管在您的示例中它不是最佳的,因为每次在Provider中调用Consumer
时,notifyListeners()
都会重建,这将是多余的,因为您的UI不会更改。