Flutter-Widget-Grundlagen

Widget ist der grundlegende Baustein der Flutter-UI.

In Flutter ist alles ein Widget; von einfachem Text bis hin zu komplexen Seitenlayouts besteht alles aus Widgets.


Was ist ein Widget?

Ein Widget ist eine Dart-Klasse, die das Aussehen und Verhalten der UI beschreibt. Jede Flutter-App ist im Wesentlichen eine Baumstruktur aus Widgets, die als Widget-Baum bezeichnet wird.

Beispiel: Das einfachste Widget-Beispiel

import 'package:flutter/material.dart';

// Ein einfaches Widget definieren
class HelloWidget extends StatelessWidget {
  const HelloWidget({super.key});

  @override
  Widget build(BuildContext context) {
    // Gibt ein Text-Widget zurück, das "Hello World" anzeigt
    return const Text('Hello World');
  }
}

StatelessWidget - zustandslose Komponente

StatelessWidget ist ein unveränderliches Widget. Nach der Erstellung können seine Eigenschaften nicht geändert werden. Es eignet sich für Szenarien, die statischen Inhalt anzeigen, wie Text, Bilder, Symbole usw.

Grundstruktur

Beispiel: StatelessWidget Beispiel

import 'package:flutter/material.dart';

// Definiere ein zustandsloses Widget
class MyTextWidget extends StatelessWidget {
  // Konstruktorparameter (unveränderliche Eigenschaften)
  final String text;
  final Color textColor;
  final double fontSize;

  // const-Konstruktor verwenden
  const MyTextWidget({
    super.key,
    required this.text,
    this.textColor = Colors.black,
    this.fontSize = 16.0,
  });

  @override
  Widget build(BuildContext context) {
    // build-Methode gibt ein weiteres Widget zurück
    return Text(
      text,
      style: TextStyle(
        color: textColor,
        fontSize: fontSize,
      ),
    );
  }
}

// Anwendungsbeispiel
// MyTextWidget(text: 'Hello', textColor: Colors.red)

Anwendbare Szenarien

  • Statische Textanzeige
  • Bildanzeige
  • Icon-Anzeige
  • Layout, das sich mit der Zeit nicht ändert

StatefulWidget - zustandsbehaftete Komponente

StatefulWidget ist ein veränderbares Widget, das die UI aktualisieren kann, wenn sich interne Daten ändern. Es eignet sich für Szenarien, die auf Benutzerinteraktionen oder Datenänderungen reagieren müssen.

Grundstruktur

Beispiel: StatefulWidget-Beispiel

import 'package:flutter/material.dart';

// Definiere ein zustandsbehaftetes Widget
class CounterWidget extends StatefulWidget {
  const CounterWidget({super.key});

  @override
  State<CounterWidget> createState() => _CounterWidgetState();
}

// State-Klasse enthält veränderlichen Zustand
class _CounterWidgetState extends State<CounterWidget> {
  // Zählerzustand
  int _count = 0;

  // Methode zum Inkrementieren des Zählers
  void _increment() {
    // Rufen Sie setState auf, um das Framework zu benachrichtigen, dass sich der Zustand geändert hat
    setState(() {
      _count++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        // Aktuellen Zählerstand anzeigen
        Text(
          'Zähler: $_count',
          style: const TextStyle(fontSize: 24),
        ),
        const SizedBox(height: 16),
        // Schaltfläche zum Erhöhen
        ElevatedButton(
          onPressed: _increment,
          child: const Text('Erhöhen'),
        ),
      ],
    );
  }
}

setState-Methode

In einem StatefulWidget müssen Sie bei einer Zustandsänderung aufrufensetStatedie Methode, um Flutter mitzuteilen, dass die UI neu aufgebaut werden soll.

Wenn der Zustand geändert wird, aber setState nicht aufgerufen wird, wird die UI nicht aktualisiert. Das liegt daran, dass Flutter setState verwendet, um festzustellen, ob das Widget neu aufgebaut werden muss.

Anwendbare Szenarien

  • Dynamische Daten wie Zähler, Timer usw.
  • Formulareingabe
  • Hinzufügen, Löschen und Ändern von Listenelementen
  • Reaktion auf Benutzerinteraktion

build-Methode

Jedes Widget muss implementierenbuilddie Methode, die einen Teil des Widget-Baums zurückgibt.

Grundregeln

RegelnBeschreibung
RückgabewertEs muss ein Widget zurückgeben und darf nicht null zurückgeben.
ParameterErhält einen BuildContext-Parameter, der die Position im Widget-Baum repräsentiert.
AufrufzeitpunktErster Build, Rebuild des übergeordneten Widgets und Zustandsänderungen

Beispiel: Beispiel für die build-Methode

@override
Widget build(BuildContext context) {
  // BuildContext bietet Zugriff auf Themes, Theme-Informationen usw.
  // Zum Beispiel die aktuelle Theme-Farbe abrufen
  final theme = Theme.of(context);

  // Ein Widget zurückgeben
  return Container(
    padding: const EdgeInsets.all(16.0),
    decoration: BoxDecoration(
      color: theme.colorScheme.primaryContainer,
      borderRadius: BorderRadius.circular(8),
    ),
    child: Text(
      'Hello Flutter',
      style: TextStyle(
        color: theme.colorScheme.onPrimaryContainer,
        fontSize: 20,
      ),
    ),
  );
}

Häufig verwendete grundlegende Widgets

Text - Textanzeige

Beispiel: Text Widget

// Grundlegender Text
const Text('Hello World')

// Text mit Stil
Text(
  'Hello Flutter',
  style: TextStyle(
    fontSize: 20,
    fontWeight: FontWeight.bold,
    color: Colors.blue,
  ),
)

// Text mit optionalem Stil
Text.rich(
  TextSpan(
    text: 'Hello ',
    children: [
      TextSpan(
        text: 'Flutter',
        style: TextStyle(fontWeight: FontWeight.bold),
      ),
    ],
  ),
)

Icon

Beispiel: Icon Widget

// Material Icons verwenden
const Icon(Icons.home)              // Home-Symbol
const Icon(Icons.star, color: Colors.yellow)  // Farbiger Stern
const Icon(Icons.settings, size: 48)  // Einstellungen-Symbol der Größe 48

Image

Beispiel: Image Widget

// Bild aus dem Netzwerk laden
Image.network('https://example.com/image.png')

// Bild aus lokalen Assets laden
Image.asset('assets/images/logo.png')

// Bild aus Datei laden
Image.file(File('path/to/image.png'))

// Bild mit Parametern
Image.network(
  'https://example.com/image.png',
  width: 200,
  height: 200,
  fit: BoxFit.cover,
)

Schaltfläche

Beispiel: Schaltflächen-Widget

// Text-Schaltfläche
TextButton(
  onPressed: () { /* Klick behandeln */ },
  child: const Text('Textschaltfläche'),
)

// Schwebende Aktionsschaltfläche
FloatingActionButton(
  onPressed: () { /* Klick behandeln */ },
  child: const Icon(Icons.add),
)

// ElevatedButton - Schaltfläche mit Schatten
ElevatedButton(
  onPressed: () { /* Klick behandeln */ },
  child: const Text('Absenden'),
)

// Schaltfläche mit Symbol
ElevatedButton.icon(
  onPressed: () { /* Klick behandeln */ },
  icon: const Icon(Icons.save),
  label: const Text('Speichern'),
)

Widget-Kombination

Die Stärke von Flutter liegt in der Fähigkeit, Widgets zu kombinieren. Durch Verschachtelung kann ein einfaches Widget eine komplexe UI aufbauen.

Beispiel: Zusammengesetztes Widget

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

  @override
  Widget build(BuildContext context) {
    return Card(
      // Card ist eine Material Design-Kartenkomponente
      elevation: 4,  // Schattentiefe
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // Titel
            const Text(
              'Card-Titel',
              style: TextStyle(
                fontSize: 20,
                fontWeight: FontWeight.bold,
              ),
            ),
            const SizedBox(height: 8),
            // Beschreibungstext
            const Text(
              'Dies ist die Beschreibung der Karte, die mehrere Textzeilen enthalten kann.',
            ),
            const SizedBox(height: 16),
            // Button-Zeile
            Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                TextButton(
                  onPressed: () {},
                  child: const Text('Abbrechen'),
                ),
                const SizedBox(width: 8),
                ElevatedButton(
                  onPressed: () {},
                  child: const Text('Bestätigen'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
Weitere Erweiterungen