Provider: Consumer
Część sekcji Zarządzanie stanem ścieżki Flutter w Coddy. Lekcja 12 z 27.
Tutaj dostawca jest tworzony wewnątrz własnej metody build widgetu MyApp, a ta sama metoda build zaraz pod nim szuka lampy. Aplikacja wyświetla błąd: context należy do MyApp, który znajduje się nad dostawcą, a widget może znaleźć tylko dostawców znajdujących się nad nim.
Rozwiązuje to widget Consumer. Jest widgetem, więc znajduje się pod dostawcą, a jego builder otrzymuje nowy context i sam model:
Consumer<Lamp>(
builder: (context, lamp, child) {
return Text(lamp.isOn ? 'On' : 'Off');
},
)Funkcja builder uruchamia się ponownie za każdym razem, gdy lampa wywoła notifyListeners(), podobnie jak widget, który ją obserwuje. W jej wnętrzu możesz wywoływać metody modelu bezpośrednio na lamp: onPressed: () => lamp.toggle().
Consumer przebudowuje też tylko to, co obejmuje, więc opakowanie zmieniającej się części pozwala zachować resztę ekranu bez zmian. W większości aplikacji użyjesz context.watch we własnym widgecie, a po Consumer sięgniesz, gdy znajdujesz się w tej samej metodzie build co dostawca.
Wyzwanie
ŚredniAplikacja uruchamia się z błędem. Umieść elementy lampy wewnątrz Consumer:
- Owiń
ColumnwConsumer<Lamp>i zwróćColumnz jego buildera. - Wewnątrz użyj
lampz buildera dla ikony, tekstu i przycisku.
Spróbuj swoich sił
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'),
),
],
),
),
),
),
);
}
}
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