在这种情况下,文档有些误导。确实,您可以在Provider
没有上下文的情况下以这种方式访问 a ,但您也在实例化一个 new ProviderContainer
,它是存储所有提供程序状态的位置。通过这样做,您正在创建然后修改一个新的Notifier
; 这意味着Notifier
您的小部件正在收听的内容保持不变。
您可以在小部件树之外使用提供程序的一种方法是ProviderContainer
在ProviderScope
. 小心这一点,因为它可能会导致意想不到的后果。
用这个替换你的main.dart
代码:
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
//Provider container which holds the state of all my providers
//This would normally be inaccessible inside of the ProviderScope
final providerContainer = ProviderContainer();
//A function that accesses and uses myNotifierProvider ***Without needing a context***
void incrementCountWithoutContext() {
var provider = providerContainer.read(myNotifierProvider);
provider.incrementCount();
}
final myNotifierProvider = ChangeNotifierProvider((_) {
return MyNotifier();
});
class MyNotifier extends ChangeNotifier {
int count = 0;
void incrementCount() {
count++;
notifyListeners();
}
}
void main() {
runApp(
//Here is where we pass in the providerContainer declared above
UncontrolledProviderScope(
container: providerContainer,
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends ConsumerWidget {
@override
Widget build(BuildContext context, ScopedReader watch) {
final _provider = watch(myNotifierProvider);
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
Text(
'${_provider.count}',
style: Theme.of(context).textTheme.headline4,
),
ElevatedButton(
//Increment count by accessing the provider the usual way
onPressed: _provider.incrementCount,
child: Text('Increment count the usual way'),
),
ElevatedButton(
//Increment the count using our global function
//Notice no context is passed to this method
onPressed: incrementCountWithoutContext,
child: Text('Increment count without context'),
)
],
),
),
);
}
}