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
// 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
// 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
// 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
| Regeln | Beschreibung |
|---|---|
| Rückgabewert | Es muss ein Widget zurückgeben und darf nicht null zurückgeben. |
| Parameter | Erhält einen BuildContext-Parameter, der die Position im Widget-Baum repräsentiert. |
| Aufrufzeitpunkt | Erster Build, Rebuild des übergeordneten Widgets und Zustandsänderungen |
Beispiel: Beispiel für die build-Methode
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
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
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
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
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
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'),
),
],
),
],
),
),
);
}
}