Nhiều mô hình: MultiProvider
Thuộc phần Quản lý trạng thái trong hành trình Flutter của Coddy. Bài học 15 trên 27.
Giữ mỗi mô hình tập trung vào một việc: điểm số ở một lớp, số mạng ở lớp khác. Mô hình nhỏ dễ đọc, còn một widget chỉ theo dõi những gì nó cần. Ứng dụng có nhiều mô hình cần nhiều provider.
Bạn có thể lồng chúng vào nhau, đặt một provider làm con của provider tiếp theo, nhưng code sẽ thụt dần sang phải theo từng mô hình. MultiProvider nhận một danh sách phẳng thay vào đó:
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => Score()),
ChangeNotifierProvider(create: (context) => Lives()),
],
child: const MyApp(),
),
);Các provider trong danh sách không có child riêng: MultiProvider xếp chồng chúng cho bạn và đặt child bên dưới tất cả. Mọi widget bên dưới đều có thể theo dõi hoặc đọc bất kỳ mô hình nào theo kiểu của mô hình đó: context.watch<Lives>().
Thử thách
DễTrang trò chơi theo dõi hai mô hình, Score và Lives, nhưng main chỉ cung cấp điểm số, nên ứng dụng báo lỗi.
- Thay provider trong
mainbằngMultiProviderđể cung cấp cả hai mô hình.
Tự làm thử
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'),
),
],
),
],
),
),
);
}
}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Quản lý trạng thái
Tự luyện tập: Trình biên dịch Flutter online