Wiele modeli: MultiProvider
Część sekcji Zarządzanie stanem ścieżki Flutter w Coddy. Lekcja 15 z 27.
Każdy model niech odpowiada za jedną rzecz: wynik w jednej klasie, życia w innej. Małe modele są łatwe do odczytania, a widżet obserwuje tylko to, czego potrzebuje. Aplikacja z kilkoma modelami potrzebuje kilku dostawców.
Możesz je zagnieździć, umieszczając jednego dostawcę jako element podrzędny kolejnego, ale kod przesuwa się w prawo z każdym modelem. MultiProvider przyjmuje zamiast tego płaską listę:
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => Score()),
ChangeNotifierProvider(create: (context) => Lives()),
],
child: const MyApp(),
),
);Dostawcy na liście nie mają własnego elementu podrzędnego child: MultiProvider układa ich za Ciebie i umieszcza child pod nimi wszystkimi. Każdy widżet poniżej może obserwować dowolny model lub odczytywać jego wartość, wskazując jego typ: context.watch<Lives>().
Wyzwanie
ŁatwyStrona gry obserwuje dwa modele, Score i Lives, ale main udostępnia tylko wynik, więc aplikacja wyświetla błąd.
- Zastąp dostawcę w
mainelementemMultiProvider, który udostępnia oba modele.
Spróbuj swoich sił
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'),
),
],
),
],
),
),
);
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Zarządzanie stanem
Poćwicz samodzielnie: Kompilator Flutter online