Lektion 09 - Flutter Counter-App
Aus Dart wird eine grafische App
Nach den Dart-Grundlagen geht es jetzt in Flutter weiter. Du nimmst das neue
Standard-Counter-Projekt, analysierst den Code und baust daraus eine deutlich
komplexere Counter-App mit mehreren Buttons.
1. Projektziel
Du erstellst ein neues Flutter-Projekt, legst daraus ein neues public Repository an
und veraenderst die Counter-App so, dass sie nicht mehr nur einen
FloatingActionButton nutzt.
01Neues Flutter-Projekt anlegen und den Startcode analysieren.
02Projekt als neues public Repository veroeffentlichen.
03FloatingActionButton entfernen.
04Mehrere unterschiedliche Counter-Buttons einbauen.
05Code so strukturieren, dass die oberste Ebene schnell lesbar ist.
2. Was ist Flutter?
Flutter ist ein Framework, mit dem du grafische Oberflaechen baust. Der Code wird
in Dart geschrieben. Eine Flutter-App besteht aus Widgets. Ein Widget ist ein
Baustein der Oberflaeche, zum Beispiel Text, Button, Spalte, Zeile oder eine ganze Seite.
Text('Hallo Flutter')
ElevatedButton(...)
Column(...)
Row(...)
3. Der Counter im Startprojekt
Im Standardprojekt gibt es eine Zahl _counter. Wenn der Button gedrueckt
wird, ruft Flutter setState auf. Dadurch wird die Zahl geaendert und die
Oberflaeche neu gezeichnet.
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
4. Planung fuer die neue App
Auch bei Flutter-Aufgaben planst du zuerst die Logik. Die Oberflaeche ist neu,
aber die Denkweise bleibt gleich: Zustand, Aktionen, Ausgabe.
Setze counter auf 0
Zeige die aktuelle Zahl an
Wenn Button "+1" gedrueckt wird:
Erhoehe counter um 1
Wenn Button "-1" gedrueckt wird:
Senke counter um 1
Wenn Button "+2" gedrueckt wird:
Erhoehe counter um 2
Wenn Button "-2" gedrueckt wird:
Senke counter um 2
Wenn Button "x2" gedrueckt wird:
Verdopple counter
Wenn Button "/2" gedrueckt wird:
Halbiere counter
Zeichne die Oberflaeche nach jeder Aenderung neu
5. Column und Row verstehen
Column ordnet Widgets von oben nach unten an. Row ordnet Widgets
von links nach rechts an. Fuer eine Button-Gruppe kannst du mehrere Rows in eine
Column legen.
Column
Column(
children: [
Text('Counter'),
Text('0'),
Row(...),
],
)
Row
Row(
children: [
ElevatedButton(...),
ElevatedButton(...),
],
)
Wichtig: children ist eine Liste. Darin stehen die Widgets, die angezeigt werden.
6. FloatingActionButton entfernen
Im Startprojekt steht im Scaffold normalerweise ein
floatingActionButton. Diese Zeile entfernst du, weil deine Buttons direkt im
Layout stehen sollen.
Vorher
Scaffold(
appBar: AppBar(...),
body: Center(...),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
child: const Icon(Icons.add),
),
)
Nachher
Scaffold(
appBar: AppBar(...),
body: Center(
child: CounterView(...),
),
)
7. Aktionen fuer den Counter
Jede Aenderung am Counter muss in setState passieren. Sonst aendert sich zwar
vielleicht ein Wert, aber Flutter zeichnet die Oberflaeche nicht neu.
void _changeCounter(int value) {
setState(() {
_counter += value;
});
}
void _doubleCounter() {
setState(() {
_counter *= 2;
});
}
void _halveCounter() {
setState(() {
_counter = (_counter / 2).round();
});
}
Bei / entsteht in Dart ein double. Darum wird mit
round() wieder eine ganze Zahl daraus.
8. Extract Widget
Wenn die oberste Ebene schnell lesbar sein soll, darf nicht alles in einer riesigen
build-Methode stehen. Du lagerst Teile in eigene Widgets aus. Das nennt man
Extract Widget.
class CounterActionButton extends StatelessWidget {
const CounterActionButton({
super.key,
required this.label,
required this.onPressed,
});
final String label;
final VoidCallback onPressed;
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: onPressed,
child: Text(label),
);
}
}
labelText, der auf dem Button steht.
onPressedFunktion, die beim Klick ausgefuehrt wird.
requiredDieser Parameter muss beim Erzeugen angegeben werden.
9. Parameter an Widgets uebergeben
Eigene Widgets werden flexibel, wenn du ihnen Werte uebergibst. So brauchst du nicht
fuer jeden Button eine eigene Klasse.
CounterActionButton(
label: '+1',
onPressed: () => _changeCounter(1),
)
CounterActionButton(
label: '-2',
onPressed: () => _changeCounter(-2),
)
() => _changeCounter(1) bedeutet: Fuehre diese Funktion erst aus, wenn der
Button gedrueckt wird.
10. Beispiel-Struktur fuer lesbaren Code
Die oberste Ebene soll schnell lesbar sein. Eine gute Struktur koennte so aussehen:
MyCounterPage
Scaffold
AppBar
Body
CounterDisplay
CounterControls
CounterActionButton
CounterActionButton
CounterActionButton
Dadurch erkennt man oben sofort: Die Seite hat Anzeige und Steuerung. Die Details
liegen in kleineren Widgets.
11. Orientierungscode
Dieser Code ist eine mögliche Richtung. Schreibe ihn nicht blind ab: Lies zuerst die
Struktur, markiere Widgets und ueberlege, welche Aufgabe jedes Widget hat.
class CounterPage extends StatefulWidget {
const CounterPage({super.key});
@override
State<CounterPage> createState() => _CounterPageState();
}
class _CounterPageState extends State<CounterPage> {
int _counter = 0;
void _changeCounter(int value) {
setState(() {
_counter += value;
});
}
void _doubleCounter() {
setState(() {
_counter *= 2;
});
}
void _halveCounter() {
setState(() {
_counter = (_counter / 2).round();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Counter App')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CounterDisplay(value: _counter),
CounterControls(
onPlusOne: () => _changeCounter(1),
onMinusOne: () => _changeCounter(-1),
onPlusTwo: () => _changeCounter(2),
onMinusTwo: () => _changeCounter(-2),
onDouble: _doubleCounter,
onHalf: _halveCounter,
),
],
),
),
);
}
}
12. Uebungen
- Lege ein neues Flutter-Projekt an und finde
main.dart.
- Markiere im Startcode
Scaffold, AppBar, body und FloatingActionButton.
- Schreibe eine kurze Planung fuer alle Counter-Aktionen.
- Entferne den
FloatingActionButton und ersetze ihn durch Buttons im body.
- Nutze mindestens eine
Column und zwei Row-Bereiche.
- Extrahiere mindestens ein eigenes Widget fuer wiederverwendbare Buttons.
- Uebergib dem Button-Widget mindestens
label und onPressed als Parameter.
- Variiere die Buttons optisch: Text, Farbe, Icon, Groesse oder Stil.
Sauberer Lernweg: Erst Startcode analysieren, dann Verhalten planen, dann Layout
planen, dann Widgets extrahieren, danach optisch variieren.
Weiter zu Widgets & Layout