Skip to Content
Mobile Apps4 - FlutterWidgets ohne State

Widgets ohne State

Dauer: 40 Minuten

  • Widgets sind UI-Komponenten
  • Styles verwenden
  • Checkbox und ListView einbauen

Ziel: Umgang mit stateless Widgets vertiefen

In Android hatten wir es mit Composables zu tun, in Flutter heißen die UI-Komponenten Widgets.

Stateless Widgets

Ein stateless Widget ist eine Klasse, die von StatelessWidget erbt und die Methode build implementiert. Wir sehen dies in unserem Code sowohl mit der Klasse MyApp als auch mit der Klasse MyHomePage:

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { // Code weggelassen // return Widget } } class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { // Code weggelassen // return Widget } }

Ein stateless Widget (StatelessWidget) hat keinen eigenen veränderlichen State, aber seine Darstellung kann sich jederzeit ändern, wenn sich seine Eingaben/Abhängigkeiten ändern — dann wird build() erneut ausgeführt und ein neuer UI-Baum erzeugt.

TodoItem als StatelessWidget

Wir erstellen nun die Klasse TodoItem als stateless Widget in einer neuen Datei lib/todo_item.dart:

// Achtung: neue Datei lib/todo_item.dart ! import 'package:flutter/material.dart'; class TodoItem extends StatelessWidget { final String title; const TodoItem({super.key, required this.title}); @override Widget build(BuildContext context) { return Text(title); } }

TodoItem wird in der Klasse MyHomePage verwendet, dazu müssen wir zunächst die Datei todo_item.dart importieren:

import 'package:flutter/material.dart'; // Achtung: Import der neuen Datei lib/todo_item.dart ! import 'package:todosflutter2025/todo_item.dart'; void main() { runApp(const MyApp()); } // Code weggelassen // In der Klasse MyHomePage: body: const Column( children: [ TodoItem(title: 'Einkaufen'), // anstatt Text-Widget TodoItem(title: 'Kochen'), TodoItem(title: 'Sport'), ], ), // Code weggelassen

Styles in TodoItem

In Flutter gibt es viele Möglichkeiten, Styles zu definieren. Hier ein paar Beispiele (Vorschlag kam von ChatGPT):

import 'package:flutter/material.dart'; class TodoItem extends StatelessWidget { final String title; const TodoItem({super.key, required this.title}); @override Widget build(BuildContext context) { final textStyle = Theme.of(context).textTheme.bodyLarge; return Padding( padding: const EdgeInsets.symmetric(vertical: 4.0), child: Text( title, style: textStyle, maxLines: 2, overflow: TextOverflow.ellipsis, ), ); } }

Theme.of(context).textTheme.bodyLarge holt den Standard-Fließtext-Stil aus dem aktuellen Material-Theme. Der Text übernimmt dadurch Theme-Eigenschaften (z. B. Schriftfamilie, Größe, Farbe) und reagiert auf Light/Dark sowie Textskalierung. Voraussetzung: ein Theme im Baum (z. B. via MaterialApp). EdgeInsets.symmetric(vertical: 2.0) gibt den Innenabstand (Padding) vor: oben 2.0 und unten 2.0 logische Pixel (insgesamt 4.0 vertikal).

Checkbox in TodoItem

Wir können das TodoItem-Widget erweitern, um eine Checkbox hinzuzufügen:

import 'package:flutter/material.dart'; class TodoItem extends StatelessWidget { final String title; const TodoItem({super.key, required this.title}); @override Widget build(BuildContext context) { final textStyle = Theme.of(context).textTheme.bodyLarge; return Padding( padding: const EdgeInsets.symmetric(vertical: 4.0), child: Row( children: [ Checkbox( value: false, onChanged: (bool? value) { /* to be implemented */ }, ), Text( title, style: textStyle, maxLines: 2, overflow: TextOverflow.ellipsis, ), ], ), ); } }

Wir implementieren die Methode onChanged später, wenn wir stateful Widgets behandeln.

Mit einer weiteren Anpassung wollen wir das ganze TodoItem antippbar machen:

import 'package:flutter/material.dart'; class TodoItem extends StatelessWidget { final String title; const TodoItem({super.key, required this.title}); @override Widget build(BuildContext context) { final textStyle = Theme.of(context).textTheme.bodyLarge; return CheckboxListTile( value: false, onChanged: (bool? value) { /* to be implemented */ }, title: Text( title, style: textStyle, maxLines: 2, overflow: TextOverflow.ellipsis, ), controlAffinity: ListTileControlAffinity.leading, ); } }

Hierzu verwenden wir das CheckboxListTile-Widget, das ein Material Design-Element ist und eine Checkbox mit einem Titel kombiniert. Damit haben wir unseren Code vereinfacht und die Antippbarkeit des gesamten Listenelements erreicht.

Es fällt auf, dass wir in Flutter weniger Import-Anweisungen benötigen als in der nativen Android-Entwicklung mit Kotlin.

TodoList-Widget mit ListView

Schließlich ersetzen wir Column für unsere drei statischen Todos durch ein ListView-Widget, um die TodoListe durch ein besseres Listen-Widget für mögliche große Todolisten zu optimieren und u.a. scrollbar zu machen.

Dazu erstellen wir zunächst eine weiteres stateless Widget in einer neuen Datei lib/todo_list.dart:

import 'package:flutter/material.dart'; import 'package:todosflutter2025/todo_item.dart'; class TodoList extends StatelessWidget { const TodoList({super.key}); @override Widget build(BuildContext context) { return ListView( children: const [ TodoItem(title: 'Einkaufen'), TodoItem(title: 'Kochen'), TodoItem(title: 'Sport'), ], ); } }

In lib/main.dart ersetzen wir den Import vom TodoItem mit TodoList und verwenden das neue Widget in der MyHomePage-Klasse:

import 'package:flutter/material.dart'; // Achtung: folgenden Import anpassen! import 'package:todosflutter2025/todo_list.dart'; // Code weggelassen class MyHomePage extends StatelessWidget { const MyHomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Todo-App'), ), body: const TodoList(), // Column durch TodoList ersetzt floatingActionButton: FloatingActionButton( onPressed: () => debugPrint('Todo hinzufügen'), tooltip: 'Todo hinzufügen', child: const Icon(Icons.add), ), ); } }

Zusammenfassung

In Flutter haben wir nun stateless Widgets kennengelernt, die als Dart-Klassen implementiert werden, von StatelessWidget erben und die Methode build implementieren. Es gibt viele vordefinierte Widgets in Flutter für UI-Komponenten, Styles, Layout usw.. Geschachtelte Widgets ergeben eine Baumstruktur, die das UI repräsentiert. Auch wenn in nativer Android-Entwicklung mit Kotlin und Compose die UI-Komponenten als Funktionen (Composables) definiert werden, gibt es viele Parallelen zwischen den beiden Frameworks.

Mehr zu Widgets in der Flutter-Dokumentation:

PAUSE

spätestens hier eine Pause einlegen