Mehrere Modelle: MultiProvider
Teil des Abschnitts State Management der Flutter-Journey von Coddy. Lektion 15 von 27.
Halte jedes Modell auf eine Sache beschränkt: die Punktzahl in einer Klasse, die Leben in einer anderen. Kleine Modelle sind leicht zu lesen, und ein Widget beobachtet nur, was es benötigt. Eine App mit mehreren Modellen benötigt mehrere Provider.
Du könntest sie verschachteln, sodass ein Provider das untergeordnete Element des nächsten ist, aber der Code rückt mit jedem Modell weiter nach rechts. MultiProvider nimmt stattdessen eine flache Liste entgegen:
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => Score()),
ChangeNotifierProvider(create: (context) => Lives()),
],
child: const MyApp(),
),
);Die Provider in der Liste haben kein eigenes child: MultiProvider stapelt sie für dich und setzt child unter alle. Jedes darunterliegende Widget kann jedes der Modelle beobachten oder auslesen, jeweils anhand seines Typs: context.watch<Lives>().
Aufgabe
EinfachDie Spielseite beobachtet zwei Modelle, Score und Lives, aber main stellt nur den Punktestand bereit, daher zeigt die App einen Fehler an.
- Ersetze den Provider in
maindurch einenMultiProvider, der beide Modelle bereitstellt.
Probier es selbst
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'),
),
],
),
],
),
),
);
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in State Management
Übe selbstständig: Online-Flutter-Compiler