Kodokon kodokon.com

Interaktivität: Buttons, StatefulWidget und setState

Erwecke deine Bildschirme zum Leben: Reagiere auf das Tippen auf Buttons und aktualisiere die Anzeige mit setState.

10 Min. · 3 Fragen

Diese Lektion in Kodokon öffnen

Unsere Bildschirme sind hübsch, aber starr: Zeit, auf die Gesten der Nutzer zu reagieren. Der Standard-Button von Material 3 ist ElevatedButton. Er nimmt zwei wesentliche Parameter entgegen: child, seinen angezeigten Inhalt (oft ein Text), und onPressed, die Funktion, die ausgeführt wird, wenn du darauf tippst. Eine so als Parameter übergebene Funktion heißt Callback: Du rufst sie nicht selbst auf, Flutter ruft sie im richtigen Moment für dich auf. Die Schreibweise () { ... } erzeugt eine anonyme Funktion, ohne Namen, direkt an Ort und Stelle geschrieben.

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

Widget buildHelloButton() {
  return ElevatedButton(
    onPressed: () {
      debugPrint("Button pressed!");
    },
    child: const Text("Tap here"),
  );
}
Ein Button, der bei jedem Tippen in die Konsole schreibt

debugPrint schreibt in die Konsole... aber der Bildschirm selbst ändert sich nicht. Warum? Weil ein StatelessWidget (ein Widget ohne Zustand) starr ist: einmal gebaut, kann es sich nicht mehr ändern. Um einen Wert anzuzeigen, der sich entwickelt, brauchst du ein StatefulWidget (ein Widget mit Zustand). Der Zustand, das ist die Menge der Daten, die sich im Leben des Widgets ändern können: ein Zähler, ein angekreuztes Kästchen, ein eingegebener Text... Ein StatefulWidget geht immer Hand in Hand mit einer Klasse State, die diese Daten aufbewahrt und die Methode build enthält. Hier der große Klassiker der ersten Schritte: der Zähler.

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

void main() {
  runApp(const CounterApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(useMaterial3: true),
      home: const CounterPage(),
    );
  }
}

class CounterPage extends StatefulWidget {
  const CounterPage({super.key});

  @override
  State<CounterPage> createState() =>
      _CounterPageState();
}

class _CounterPageState extends State<CounterPage> {
  int count = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              "Counter: $count",
              style: const TextStyle(fontSize: 32),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  count = count + 1;
                });
              },
              child: const Text("+1"),
            ),
          ],
        ),
      ),
    );
  }
}
Der Zähler: ein vollständiges StatefulWidget

Der Mechanismus läuft in drei Schritten ab. 1) Die Variable count lebt in _CounterPageState: Das ist der Zustand. 2) Bei jedem Tippen ruft der Callback setState auf: Diese Methode ändert den Zustand und teilt Flutter mit, dass sich etwas geändert hat. 3) Flutter führt dann build erneut aus, was den Bildschirm mit dem neuen Wert von count neu zeichnet. Merke dir die Philosophie: Du änderst nie direkt den Bildschirm, du änderst die Daten, und Flutter kümmert sich um die Anzeige.

Wissenscheck

Stelle sicher, dass du die wichtigsten Punkte dieser Lektion behalten hast.

  1. Wozu dient der Parameter onPressed eines ElevatedButton?
    • Um den auf dem Button angezeigten Text festzulegen
    • Um die Funktion bereitzustellen, die beim Tippen auf den Button ausgeführt wird
    • Um die Farbe des Buttons zu wählen
  2. Wann solltest du ein StatefulWidget statt eines StatelessWidget verwenden?
    • Wenn die Anzeige von Daten abhängt, die sich mit der Zeit ändern
    • Wenn das Widget mehr als drei Kinder enthält
    • Wenn du willst, dass die App schneller startet
  3. Was passiert, wenn du count änderst, ohne setState aufzurufen?
    • Die App stürzt sofort ab
    • Die Variable ändert sich im Speicher, aber der Bildschirm wird nicht aktualisiert
    • Flutter ruft setState automatisch für dich auf