Theme und ThemeData — die zentralen Mechanismen der Thematisierung in Flutter, die es ermöglichen, Farben, Schriftarten, Abstände und Komponentenstile global für die gesamte Anwendung festzulegen. ThemeData ist ein Konfigurationsobjekt, das über den Parameter theme an MaterialApp übergeben wird. Laut der offiziellen Flutter-Dokumentation (2026) reduziert die richtige Konfiguration von ThemeData doppelten Styling-Code um 70–80% und sorgt für ein einheitliches Erscheinungsbild auf allen Bildschirmen. Das integrierte Vererbungssystem ermöglicht das Überschreiben des Themas auf der Ebene einzelner Widgets über Theme.of(context).
Wichtige Punkte
ThemeData ist eine Klasse, die die vollständige Beschreibung des visuellen Stils einer Material-Anwendung enthält. Sie wird über den Parameter theme oder darkTheme an MaterialApp übergeben und von allen untergeordneten Widgets geerbt. Jedes Material Design Widget verwendet ThemeData, um seine Stile zu erhalten: Button-Farben, AppBar-Größen, Textstile, Kartenabstände und Symbole.
Im Kern von ThemeData liegt ColorScheme, das die Farben primary, secondary, surface, error und andere definiert. Aus diesen Farben werden automatisch die Zustände (hover, focus, pressed) für alle Material-Komponenten berechnet. Beispielsweise verwendet ElevatedButton die Primärfarbe für den Hintergrund und onPrimary für den Text — ohne zusätzliche Konfiguration.
Das Theme Widget ist ein InheritedWidget, das das Thema im Widget-Baum nach unten propagiert. Jedes Widget kann über Theme.of(context) auf das aktuelle Thema zugreifen und auch ein neues Thema basierend auf dem bestehenden mit überschriebenen Werten über Theme.copyWith oder ThemeData.copyWith erstellen.
Zusammenfassung: ThemeData ist die einzige Quelle für Stile der Anwendung. Beginnen Sie die Entwicklung mit der Definition von ThemeData — dies legt die visuelle Sprache des gesamten Projekts fest und verhindert verstreute Stile auf verschiedenen Bildschirmen.
ColorScheme ist das zentrale Element der Thematisierung in Material 3. Es ersetzt die veralteten primarySwatch und primaryColor und bietet einen vollständigen Satz von Farben für alle Zustände und Komponenten.
ColorScheme enthält 12 Hauptfarben: primary, onPrimary, secondary, onSecondary, surface, onSurface, error, onError, background, onBackground, outline und shadow. Für jede Farbe werden automatisch helle und dunkle Varianten sowie Farben für die Zustände hover, focus, pressed und dragged berechnet. Wenn nur primary angegeben wird, generiert das Framework die restlichen Farben automatisch über ColorScheme.fromSeed.
Die Methode ColorScheme.fromSeed (Material 3) nimmt eine Basisfarbe seedColor und generiert eine vollständige harmonische Palette basierend auf dem Material Design 3 Algorithmus. Dies macht die manuelle Auswahl von Komplementär- und Analogfarben überflüssig. Einfach eine primäre Markenfarbe übergeben, und ColorScheme.fromSeed erstellt eine kohärente Palette für das gesamte Material-System.
Zusammenfassung: Verwenden Sie in neuen Projekten ColorScheme.fromSeed zur Generierung der Palette. Für Material 2-Kompatibilität — verwenden Sie primarySwatch. ColorScheme ist das Minimum für Material 3.
TextTheme ist ein Teil von ThemeData, der die Textstile für alle Überschriftenebenen, Unterüberschriften, Fließtext und Beschriftungen definiert. Material Design definiert 15 Textstile: headlineLarge, headlineMedium, headlineSmall, titleLarge, titleMedium und andere.
Die Typografie wird entweder über GoogleFonts zum automatischen Laden von Schriftarten oder über das integrierte Theme.of(context).textTheme mit benutzerdefinierten TextStyle-Objekten festgelegt. GoogleFonts bietet Hunderte von Schriftarten über das Paket google_fonts, die nach dem ersten Laden lokal zwischengespeichert werden. Die Alternative besteht darin, Schriftarten über pubspec.yaml in die Projekt-Assets einzubetten.
Für adaptive Typografie unterstützt TextTheme MediaQuery.textScaleFactor — wenn die Systemschriftgröße erhöht wird, werden alle Textstile proportional skaliert. Zusätzlich können verschiedene Schriftgrößen für verschiedene Formfaktoren über isTest in Abhängigkeit von MediaQuery.size.width festgelegt werden.
Zusammenfassung: Definieren Sie TextTheme in ThemeData und verwenden Sie Theme.of(context).textTheme für alle Textelemente. Dies gewährleistet Schriftkonsistenz und vereinfacht globale Typografieänderungen.
Theme ist ein InheritedWidget, das das Thema von Eltern an Kinder propagiert. Jedes untergeordnete Widget kann sowohl das aktuelle Thema über Theme.of(context) lesen als auch seine eigene Kopie mit Änderungen über ThemeData.copyWith erstellen.
Vererbungsmechanismus: Wenn ein Widget in ein Theme mit neuen Daten eingewickelt ist, sehen alle seine Nachkommen das überschriebene Thema, während Widgets außerhalb dieser Umhüllung das Original sehen. Dies ermöglicht es beispielsweise, Stile für einen bestimmten Bildschirm zu isolieren: Ein Header verwendet ein benutzerdefiniertes Thema mit einem geänderten AppBarTheme, während der Rest der Anwendung das Standard-Thema verwendet.
Die Verschachtelung von Theme kann unbegrenzt sein. Flutter verwendet eine hierarchische Suche: Beim Aufruf von Theme.of(context) steigt das Framework im Baum nach oben zum ersten Theme und gibt dessen Thema zurück. Wenn kein Theme gefunden wird — wird eine Ausnahme ausgelöst. Daher umschließt MaterialApp die Anwendung immer in einem Theme.
Zusammenfassung: Theme-Vererbung ist ein flexibler Mechanismus zur Stilisolierung. Verwenden Sie das Überschreiben des Themas für einzelne Bildschirme, ohne die globale Konfiguration zu duplizieren.
Dark Theme ist die integrierte Fähigkeit von Flutter, zwischen hellem und dunklem Thema zu wechseln. ThemeData wird in den Parametern theme (hell) und darkTheme (dunkel) von MaterialApp gespeichert. Der Parameter themeMode steuert den Modus: ThemeMode.light (immer hell), ThemeMode.dark (immer dunkel) oder ThemeMode.system (folgt den Systemeinstellungen).
Bei der Implementierung eines dunklen Themas müssen nicht alle Stile von Grund auf neu erstellt werden. Übergeben Sie einfach ColorScheme.fromSeed(seedColor, brightness: Brightness.dark) an darkTheme. Das Framework passt die Farben automatisch für einen dunklen Hintergrund an: surface wird dunkelgrau, Text wird hell. Andere Unterthemen (AppBarTheme, CardTheme, BottomNavigationBarTheme) werden von der hellen Version geerbt, sofern nicht explizit überschrieben.
Für sanfte Übergänge zwischen Themen bietet Flutter Animation über AnimatedTheme. Beim Wechsel von themeMode animieren Farben und Stile und erzeugen einen visuell ansprechenden Übergang. AnimatedTheme verwendet Duration und Curve zur Konfiguration der Animationsgeschwindigkeit.
Zusammenfassung: Das dunkle Thema wird über darkTheme und ColorScheme.fromSeed mit brightness: Brightness.dark implementiert. Verwenden Sie ThemeMode.system, um den Systemeinstellungen des Benutzers zu folgen.
Beispiel 1 — globale Theme-Konfiguration über MaterialApp mit ColorScheme.fromSeed.
final ThemeData appTheme = ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.indigo,
brightness: Brightness.light,
),
appBarTheme: const AppBarTheme(
centerTitle: true,
elevation: 0,
),
cardTheme: const CardTheme(
elevation: 2,
margin: EdgeInsets.all(8),
),
);
return MaterialApp(
theme: appTheme,
themeMode: ThemeMode.system,
home: const MyHomePage(),
);
Dieses Beispiel erstellt ein ThemeData mit Material 3, einem auf Indigo basierenden Farbschema und benutzerdefinierten AppBar- und Card-Stilen. useMaterial3 aktiviert das neue Material 3 Theming-System, und ColorScheme.fromSeed generiert die vollständige Palette.
Beispiel 2 — Zugriff auf das Thema und Überschreiben für einen Teil der Anwendung.
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Column(
children: [
Text(
'Standard headline',
style: theme.textTheme.headlineMedium,
),
Theme(
data: theme.copyWith(
colorScheme: theme.colorScheme.copyWith(
primary: Colors.orange,
),
),
child: const SpecialSection(),
),
],
);
}
Das zweite Beispiel zeigt die Verwendung von Theme.of(context) zum Lesen von Stilen und Theme() mit copyWith zum Überschreiben des Themas in einem Teil des Baums ohne Änderung der globalen Konfiguration. SpecialSection innerhalb von Theme erhält die orange Primärfarbe, während der Rest der Anwendung das ursprüngliche Indigo behält.
Zusammenfassung: Das globale Thema wird in MaterialApp festgelegt, über Theme.of(context) zugegriffen und über Theme mit copyWith überschrieben. Für Material 3 verwenden Sie ColorScheme.fromSeed.
Fehler 1: Verwendung von primarySwatch anstelle von ColorScheme in Material 3. primarySwatch ist veraltet und wird in Material 3 nicht unterstützt. Bei Verwendung von useMaterial3: true mit primarySwatch gibt Flutter eine Warnung aus. Lösung: Wechseln Sie zu ColorScheme.fromSeed für die Palettengenerierung.
Fehler 2: Hartcodieren von Farben in Widgets anstelle der Verwendung von Theme.of(context). Entwickler schreiben Colors.blue direkt in ein Container, anstatt die Primär- oder Sekundärfarbe aus dem Thema zu verwenden. Beim Wechsel des Themas bleiben diese Farben unverändert und brechen den einheitlichen Stil. Lösung: Verwenden Sie immer Theme.of(context).colorScheme.primary oder andere Farben aus dem Thema.
Fehler 3: Fehlen von darkTheme. Wenn die Anwendung kein darkTheme definiert, versucht Flutter beim Aktivieren des dunklen Themas auf dem Gerät, das helle Thema automatisch anzupassen, was oft zu einem minderwertigen Ergebnis führt. Lösung: Übergeben Sie immer darkTheme an MaterialApp, auch wenn das dunkle Thema keine Priorität hat — dies ist eine wichtige UX für Benutzer.
Fehler 4: Erstellen eines neuen Themas bei jedem Build. Wenn ThemeData innerhalb der build-Methode erstellt wird, erzeugt jeder Widget-Neubau ein neues Themenobjekt, was die Optimierung von InheritedWidget beeinträchtigt. Lösung: Verschieben Sie ThemeData in ein static-Feld oder einen const-Konstruktor außerhalb von build.
Zusammenfassung: Korrekte Thematisierung erfordert einen zentralisierten Ansatz. Verschieben Sie ThemeData in Konstanten, verwenden Sie Farbschemata aus dem Thema und definieren Sie immer beide Themen — hell und dunkel.
Häufig gestellte Fragen
ThemeData sind die Konfigurationsdaten (Farben, Schriftarten, Stile). Theme ist ein InheritedWidget, das ThemeData im Widget-Baum nach unten weitergibt. Theme.of(context) gibt das ThemeData zurück, das das nächste Theme im aktuellen Kontext propagiert.
Steuern Sie themeMode in MaterialApp über den Anwendungszustand. Ändern Sie den Zustand von ThemeMode.light auf ThemeMode.dark, und Flutter baut den gesamten Baum mit dem neuen Thema neu auf. Für sanfte Animationen verwenden Sie AnimatedTheme.
ColorScheme.fromSeed ist eine Material 3-Methode, die eine Basisfarbe (seedColor) nimmt und eine vollständige harmonische Palette generiert: primary, secondary, tertiary, surface, error und deren on-Varianten. Ermöglicht ein konsistentes Farbschema aus einer einzigen Markenfarbe.
Über TextTheme innerhalb von ThemeData: Geben Sie TextStyle mit fontFamily für jede Ebene an. Für Google Fonts verwenden Sie das Paket google_fonts und übergeben fontFamily direkt an TextTheme. Für lokale Schriftarten — binden Sie sie über pubspec.yaml im Abschnitt fonts ein.
Ja. Wickeln Sie den Bildschirm in ein Theme mit überschriebenen Daten über copyWith ein. Alle untergeordneten Widgets innerhalb dieses Themes erhalten die geänderten Stile, während der Rest der Anwendung das ursprüngliche Thema behält. Dies erzeugt keinen zusätzlichen Overhead.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch