前言
override算是Riverpod里面的一个高级技能,你要是不在代码里弄上一点,你都不好意思跟别人说你熟悉Riverpod,作为最后一篇,我们还是从Demo开始,由浅入深的了解一下override的妙用。
Demo
override的使用一般就三步:
- 第一步:根据需求选择一个Provider,如果没有初始化值就先抛出异常
final itemProvider = Provider((ref) {
throw UnimplementedError();
})
- 第二步:ProviderScope中有个overrides集合,专门用来复写Provider。Scope是范围的意思,所以这个复写的有效性也就局限在此ProviderScope中,超过这个范围使用Provider是无效的
ProviderScope(
overrides: [
itemProvider.overrideWithValue(numbers[index]),
],
child: item,
)
- 第三步:在ProviderScope子组件中使用被复写的Provider
String title = ref.watch(itemProvider);
Demo的效果如下,就是使用ListView展示一个列表,列表Item的数据来源于Provider而不是传参
代码入口
void main() {
runApp(const ProviderScope(child: OverrideApp()));
}
class OverrideApp extends StatelessWidget {
const OverrideApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(home: _Home());
}
}
主要代码
// 30条模拟数据
List<String> numbers = List.generate(30, (index) => index.toString());
// 空壳,目前还不知道提供什么数据,用于运行时被覆盖
final itemProvider = Provider<String>((ref) {
throw UnimplementedError();
});
class _Home extends ConsumerWidget {
const _Home();
@override
Widget build(BuildContext context, WidgetRef widgetRef) {
return Scaffold(
appBar: AppBar(title: const Text('Home')),
body: ListView.separated(
itemCount: numbers.length,
itemBuilder: (context, index) {
//关键点 item使用const关键字修饰
var item= const Item();
print("${identityHashCode(item)} --- ${numbers[index]}");
// 核心代码 在ProviderScope中对itemProvider进行复写
return ProviderScope(
overrides: [
itemProvider.ov