Menu
CoddyTech

Riverpod: Notifier

Teil des Abschnitts State Management der Flutter-Journey von Coddy. Lektion 19 von 27.

Ein StateProvider eignet sich für eine einzelne Zahl. Wenn der Zustand Regeln umfasst, zum Beispiel eine Liste mit Methoden zum Hinzufügen und Entfernen, schreibst du einen Notifier: eine Klasse, die den Zustand und die Methoden zu seiner Änderung enthält.

class GuestList extends Notifier<List<String>> {
  @override
  List<String> build() => [];

  void add(String name) {
    state = [...state, name];
  }
}

final guestsProvider =
    NotifierProvider<GuestList, List<String>>(GuestList.new);

build gibt den ersten Zustand zurück, eine leere Liste. Innerhalb der Klasse ist state der aktuelle Wert. GuestList.new ist der Konstruktor der Klasse, der dem Provider übergeben wird, damit dieser den Notifier erstellen kann.

Die wichtigste Regel: weise state einen neuen Wert zu, ändere niemals den alten. Riverpod informiert die Widgets nur, wenn state ein anderes Objekt zugewiesen wird. state.add(name) ändert die Liste direkt, sodass state weiterhin dieselbe Liste ist und niemand davon erfährt. [...state, name] erstellt eine neue Liste: Die drei Punkte fügen alle bisherigen Namen darin ein, dann kommt der neue Name ans Ende.

Ein Widget ruft eine Methode über den Notifier auf: ref.read(guestsProvider.notifier).add('Ada'). Diese Seite ist ein ConsumerStatefulWidget, also die zustandsbehaftete Variante, weil sie außerdem einen Text-Controller verwaltet. Die zugehörige State-Klasse hat ref als Feld.

challenge icon

Aufgabe

Schwer

Die Gästeliste zeigt die Namen in guestsProvider, aber Add leert nur das Feld.

  • Füge GuestList eine Methode add(String name) hinzu, die state auf eine neue Liste setzt, in der der Name am Ende steht.
  • Sorge dafür, dass Add die Methode mit dem Text des Feldes aufruft, bevor es das Feld leert.

Probier es selbst

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class GuestList extends Notifier<List<String>> {
  @override
  List<String> build() => [];
}

final guestsProvider = NotifierProvider<GuestList, List<String>>(GuestList.new);

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: PartyPage(),
    );
  }
}

class PartyPage extends ConsumerStatefulWidget {
  const PartyPage({super.key});

  @override
  ConsumerState<PartyPage> createState() => _PartyPageState();
}

class _PartyPageState extends ConsumerState<PartyPage> {
  final controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    final guests = ref.watch(guestsProvider);
    return Scaffold(
      appBar: AppBar(title: Text('Guests: ${guests.length}')),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(16),
            child: Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: controller,
                    decoration: const InputDecoration(labelText: 'Guest name'),
                  ),
                ),
                const SizedBox(width: 8),
                ElevatedButton(
                  onPressed: () {
                    controller.clear();
                  },
                  child: const Text('Add'),
                ),
              ],
            ),
          ),
          Expanded(
            child: ListView(
              children: [
                for (final name in guests) ListTile(leading: const Icon(Icons.person), title: Text(name)),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
quiz iconTeste dich selbst

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