Provider:共享一个模型
本课属于 Coddy Flutter 学习旅程的“状态管理”单元。第 9 课,共 27 课。
当组件彼此靠近时,向上提升状态很有效。如果整个应用的多个地方都需要某个值,比如两个屏幕、顶部栏或列表深处,你就得通过中间的每个组件传递它。Provider 可以省去这一步。它是一个包:一组通过 import 'package:provider/provider.dart'; 导入的代码。
它由三部分组成。第一部分是 模型:一个保存数据并且 extends ChangeNotifier 的类。它的方法会修改数据,然后调用 notifyListeners():
class CupCounter extends ChangeNotifier {
int _cups = 0;
int get cups => _cups;
void addCup() {
_cups++;
notifyListeners();
}
}第二部分是在组件树较高处的 ChangeNotifierProvider,它会创建一次模型,并将其提供给下方的每个组件:
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => CupCounter(),
child: const MyApp(),
),
);
}第三部分是下方的任意组件都可以获取它:使用 context.watch<CupCounter>() 来显示数据,使用 context.read<CupCounter>() 来调用方法。下方的标题和按钮会获取同一个计数器,而且不需要向它们传递任何内容。
挑战
中等打开应用:它会显示错误,因为标题需要一个 CupCounter,而上方没有提供这个对象。
- 在
main中,用会创建CupCounter的ChangeNotifierProvider包裹MyApp。
亲手试试
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class CupCounter extends ChangeNotifier {
int _cups = 0;
int get cups => _cups;
void addCup() {
_cups++;
notifyListeners();
}
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const CupsTitle()),
body: const Center(child: AddCupButton()),
);
}
}
class CupsTitle extends StatelessWidget {
const CupsTitle({super.key});
@override
Widget build(BuildContext context) {
final counter = context.watch<CupCounter>();
return Text('Cups: ${counter.cups}');
}
}
class AddCupButton extends StatelessWidget {
const AddCupButton({super.key});
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
context.read<CupCounter>().addCup();
},
child: const Text('Another cup'),
);
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
状态管理中的所有课
3Provider
Provider:共享一个模型调用 notifyListenersProvider:监听还是读取Provider:Consumer两个屏幕,一个模型模型中的对象列表多个模型:MultiProvider自己练习: Flutter 在线编译器