Provider: Consumer
Teil des Abschnitts State Management der Flutter-Journey von Coddy. Lektion 12 von 27.
Hier wird der Provider im eigenen build von MyApp erstellt, und dasselbe build fragt direkt darunter die Lampe ab. Die App zeigt einen Fehler an: context gehört zu MyApp, das sich über dem Provider befindet, und ein Widget kann Provider nur oberhalb von sich selbst finden.
Ein Consumer löst das Problem. Es ist ein Widget und befindet sich daher unterhalb des Providers. Sein builder erhält ein frisches context und das Modell selbst:
Consumer<Lamp>(
builder: (context, lamp, child) {
return Text(lamp.isOn ? 'On' : 'Off');
},
)Der Builder wird jedes Mal erneut ausgeführt, wenn die Lampe notifyListeners() aufruft, wie bei einem Widget, das sie beobachtet. Darin kannst du die Methoden des Modells direkt auf lamp aufrufen: onPressed: () => lamp.toggle().
Ein Consumer erstellt außerdem nur den Bereich neu, den es umschließt. Wenn du also den Teil umschließt, der sich ändert, bleibt der Rest des Bildschirms unverändert. In den meisten Apps verwendest du context.watch in einem eigenen Widget und greifst auf Consumer zurück, wenn du dich im selben build wie der Provider befindest.
Aufgabe
MittelDie App wird mit einem Fehler geöffnet. Füge die Bestandteile der Lampe in einen Consumer ein:
- Umschließe die
Columnmit einemConsumer<Lamp>und gib dieColumnaus dessen Builder zurück. - Verwende darin das
lampdes Builders für das Symbol, den Text und die Schaltfläche.
Probier es selbst
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Lamp extends ChangeNotifier {
bool _isOn = false;
bool get isOn => _isOn;
void toggle() {
_isOn = !_isOn;
notifyListeners();
}
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => Lamp(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(title: const Text('Lamp')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
context.watch<Lamp>().isOn ? Icons.lightbulb : Icons.lightbulb_outline,
size: 96,
color: context.watch<Lamp>().isOn ? Colors.amber : Colors.grey,
),
Text(context.watch<Lamp>().isOn ? 'The lamp is on' : 'The lamp is off'),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => context.read<Lamp>().toggle(),
child: const Text('Switch'),
),
],
),
),
),
),
);
}
}
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