多个模型:MultiProvider
本课属于 Coddy Flutter 学习旅程的“状态管理”单元。第 15 课,共 27 课。
让每个模型只负责一件事:一个类负责分数,另一个类负责生命值。小模型易于阅读,组件也只需监听自己需要的内容。包含多个模型的应用需要多个 Provider。
你可以将它们嵌套起来,让一个 Provider 成为下一个 Provider 的子级,但每增加一个模型,代码就会向右缩进。MultiProvider 接收一个扁平列表:
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => Score()),
ChangeNotifierProvider(create: (context) => Lives()),
],
child: const MyApp(),
),
);列表中的 Provider 都没有自己的 child:MultiProvider 会为你将它们叠加起来,并把 child 放在它们的下方。下面的每个组件都可以按模型的类型监听或读取任意模型,例如:context.watch<Lives>()。
挑战
简单游戏页面会监听两个模型 Score 和 Lives,但 main 只提供了分数模型,因此应用会显示错误。
- 将
main中的 provider 替换为MultiProvider,以提供这两个模型。
亲手试试
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Score extends ChangeNotifier {
int _points = 0;
int get points => _points;
void hit() {
_points += 10;
notifyListeners();
}
}
class Lives extends ChangeNotifier {
int _left = 3;
int get left => _left;
void miss() {
if (_left > 0) {
_left--;
notifyListeners();
}
}
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => Score(),
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: GamePage(),
);
}
}
class GamePage extends StatelessWidget {
const GamePage({super.key});
@override
Widget build(BuildContext context) {
final points = context.watch<Score>().points;
final lives = context.watch<Lives>().left;
return Scaffold(
appBar: AppBar(title: Text('Lives: $lives')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Points: $points', style: const TextStyle(fontSize: 40)),
const SizedBox(height: 16),
Row(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: () => context.read<Score>().hit(),
child: const Text('Hit'),
),
const SizedBox(width: 16),
ElevatedButton(
onPressed: () => context.read<Lives>().miss(),
child: const Text('Miss'),
),
],
),
],
),
),
);
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
状态管理中的所有课
3Provider
Provider:共享一个模型调用 notifyListenersProvider:监听还是读取Provider:Consumer两个屏幕,一个模型模型中的对象列表多个模型:MultiProvider自己练习: Flutter 在线编译器