Menu
CoddyTech

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.

challenge icon

Wyzwanie

Średni

Aplikacja uruchamia się z błędem. Umieść elementy lampy wewnątrz Consumer:

  • Owiń Column w Consumer<Lamp> i zwróć Column z jego buildera.
  • Wewnątrz użyj lamp z 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'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
quiz iconSprawdź się

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