Theme en ThemeData — de centrale themamechanismen in Flutter waarmee u kleuren, lettertypen, marges en componentstijlen wereldwijd voor de hele applicatie kunt instellen. ThemeData is een configuratieobject dat wordt doorgegeven aan MaterialApp via de parameter theme. Volgens de officiële Flutter-documentatie (2026) vermindert een correcte configuratie van ThemeData de hoeveelheid dubbele stijlcode met 70–80% en zorgt het voor een uniform uiterlijk van schermen. Het ingebouwde overervingssysteem maakt het mogelijk om het thema op het niveau van individuele widgets te overschrijven via Theme.of(context).
Belangrijkste punten
ThemeData — klasse die de volledige beschrijving van de visuele stijl van een Material-applicatie bevat. Het wordt doorgegeven aan MaterialApp via de parameter theme of darkTheme en wordt geërfd door alle onderliggende widgets. Elke Material Design-widget gebruikt ThemeData om zijn stijlen te verkrijgen: knopkleuren, AppBar-afmetingen, tekststijlen, kaartmarges en pictogrammen.
Aan de basis van ThemeData ligt ColorScheme, dat primary, secondary, surface, error en andere kleuren definieert. Uit deze kleuren worden automatisch de statussen (hover, focus, pressed) voor alle Material-componenten berekend. Bijvoorbeeld, ElevatedButton gebruikt de primary-kleur voor de achtergrond en onPrimary voor de tekst — zonder extra configuratie.
De widget Theme — is een InheritedWidget die het thema doorgeeft in de widgetboom. Elke widget kan het huidige thema verkrijgen via Theme.of(context) en ook een nieuw thema maken op basis van een bestaande met overschreven waarden via Theme.copyWith of ThemeData.copyWith.
Conclusie: ThemeData — de enige bron van stijlen voor de applicatie. Begin de ontwikkeling met het definiëren van ThemeData — dit stelt de visuele taal van het hele project vast en voorkomt verspreide stijlen op verschillende schermen.
ColorScheme — het centrale element van thematisering in Material 3. Het vervangt de verouderde primarySwatch en primaryColor en biedt een volledige set kleuren voor alle statussen en componenten.
ColorScheme bevat 12 basiskleuren: primary, onPrimary, secondary, onSecondary, surface, onSurface, error, onError, background, onBackground, outline en shadow. Voor elke kleur worden automatisch de light- en dark-varianten berekend, evenals kleuren voor de statussen hover, focus, pressed en dragged. Bij het opgeven van alleen primary genereert het framework de overige kleuren automatisch via ColorScheme.fromSeed.
De methode ColorScheme.fromSeed (Material 3) ontvangt een basiskleur seedColor en genereert een volledig harmonieus palet op basis van het Material Design 3-algoritme. Dit elimineert het handmatig selecteren van complementary en analogous kleuren. Het is voldoende om één hoofdmerk kleur door te geven, en ColorScheme.fromSeed creëert een samenhangend palet voor het hele Material-systeem.
Conclusie: gebruik in nieuwe projecten ColorScheme.fromSeed voor het genereren van het palet. Voor Material 2-compatibiliteit — primarySwatch. ColorScheme is het verplichte minimum voor Material 3.
TextTheme — onderdeel van ThemeData dat de tekststijlen definieert voor alle niveaus van koppen, subkoppen, body en labels. Material Design definieert 15 tekststijlen: headlineLarge, headlineMedium, headlineSmall, titleLarge, titleMedium en andere.
Typografie wordt ingesteld via GoogleFonts voor automatisch laden van lettertypen of via ingebouwde Theme.of(context).textTheme met aangepaste TextStyle. GoogleFonts biedt honderden lettertypen via het pakket google_fonts, dat ze lokaal cachet na de eerste keer laden. Alternatief — lettertypen in de projectassets insluiten via pubspec.yaml.
Voor adaptieve typografie ondersteunt TextTheme MediaQuery.textScaleFactor — bij het vergroten van het systeemlettertype worden alle tekststijlen proportioneel geschaald. Aanvullend kunnen verschillende lettergroottes worden ingesteld voor verschillende vormfactoren via isTest afhankelijk van MediaQuery.size.width.
Conclusie: definieer TextTheme in ThemeData en gebruik Theme.of(context).textTheme voor alle tekstuele elementen. Dit zorgt voor uniformiteit van lettertypen en vereenvoudigt wereldwijde wijzigingen in de typografie.
Theme — InheritedWidget die het thema verspreidt van ouder naar kinderen. Elke onderliggende widget kan zowel het huidige thema lezen via Theme.of(context) als zijn eigen kopie maken met wijzigingen via ThemeData.copyWith.
Overervingsmechanisme: als een widget is ingepakt in een Theme met nieuwe gegevens, zien al zijn afstammelingen het overschreven thema, terwijl widgets buiten deze verpakking het originele thema zien. Dit maakt het mogelijk om bijvoorbeeld stijlen te isoleren voor een specifiek scherm: de kop gebruikt een aangepast thema met gewijzigd AppBarTheme, en de rest van de applicatie gebruikt het standaardthema.
Nesting van Theme kan onbeperkt zijn. Flutter gebruikt hiërarchisch zoeken: bij het aanroepen van Theme.of(context) gaat het framework omhoog in de boom tot de eerste Theme en retourneert het thema ervan. Als er geen Theme wordt gevonden — wordt er een uitzondering gegenereerd. Daarom wikkelt MaterialApp de applicatie altijd in een Theme.
Conclusie: overerving van Theme — een flexibel mechanisme voor het isoleren van stijlen. Gebruik het overschrijven van thema's voor individuele schermen zonder de algemene configuratie te dupliceren.
Dark theme — de ingebouwde mogelijkheid van Flutter om te schakelen tussen licht en donker thema. ThemeData wordt opgeslagen in de parameters theme (licht) en darkTheme (donker) van MaterialApp. De parameter themeMode beheert de modus: ThemeMode.light (altijd licht), ThemeMode.dark (altijd donker) of ThemeMode.system (volgt systeeminstellingen).
Bij het implementeren van een donker thema hoeft u niet alle stijlen opnieuw te maken. Het is voldoende om ColorScheme.fromSeed(seedColor, brightness: Brightness.dark) door te geven in darkTheme. Het framework past automatisch de kleuren aan voor een donkere achtergrond: surface wordt donkergrijs, tekst wordt licht. De overige subthema's (AppBarTheme, CardTheme, BottomNavigationBarTheme) worden geërfd van de lichte versie, tenzij ze expliciet zijn overschreven.
Voor een vloeiende overgang tussen thema's biedt Flutter animatie via AnimatedTheme. Bij het wijzigen van themeMode worden kleuren en stijlen geanimeerd, wat een visueel prettige omschakeling creëert. AnimatedTheme gebruikt Duration en Curve om de animatiesnelheid in te stellen.
Conclusie: dark theme wordt geïmplementeerd via darkTheme en ColorScheme.fromSeed met brightness: Brightness.dark. Gebruik ThemeMode.system om de systeeminstellingen van de gebruiker te volgen.
Voorbeeld 1 — globale themaconfiguratie via MaterialApp met 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(),
);
In dit voorbeeld wordt ThemeData gemaakt met Material 3, een kleurenschema gebaseerd op indigo en aangepaste AppBar- en Card-stijlen. useMaterial3 activeert het nieuwe Material 3-themasysteem en ColorScheme.fromSeed genereert het volledige palet.
Voorbeeld 2 — toegang tot het thema en overschrijven voor een deel van de applicatie.
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Column(
children: [
Text(
'Standaardkop',
style: theme.textTheme.headlineMedium,
),
Theme(
data: theme.copyWith(
colorScheme: theme.colorScheme.copyWith(
primary: Colors.orange,
),
),
child: const SpecialSection(),
),
],
);
}
Het tweede voorbeeld toont het gebruik van Theme.of(context) voor het lezen van stijlen en Theme() met copyWith voor het overschrijven van het thema in een deel van de boom zonder de globale configuratie te wijzigen. SpecialSection binnen Theme krijgt de oranje primary-kleur, de rest van de applicatie behoudt het originele indigo.
Conclusie: het globale thema wordt ingesteld in MaterialApp, toegang via Theme.of(context), overschrijven via Theme met copyWith. Gebruik voor Material 3 ColorScheme.fromSeed.
Fout 1: gebruik van primarySwatch in plaats van ColorScheme in Material 3. primarySwatch is verouderd en wordt niet ondersteund in Material 3. Bij gebruik van useMaterial3: true met primarySwatch geeft Flutter een waarschuwing. Oplossing: overstappen op ColorScheme.fromSeed voor het genereren van het palet.
Fout 2: hardcoderen van kleuren in widgets in plaats van Theme.of(context) te gebruiken. Ontwikkelaars schrijven Colors.blue rechtstreeks in Container in plaats van de primary- of secondary-kleur uit het thema. Bij het wisselen van thema blijven dergelijke kleuren ongewijzigd, wat de uniforme stijl doorbreekt. Oplossing: gebruik altijd Theme.of(context).colorScheme.primary of andere kleuren uit het thema.
Fout 3: ontbreken van darkTheme. Als de applicatie geen darkTheme definieert, probeert Flutter bij het inschakelen van het donkere thema op het apparaat het lichte thema automatisch aan te passen, wat vaak een kwalitatief slecht resultaat geeft. Oplossing: geef altijd darkTheme door in MaterialApp, zelfs als het donkere thema geen prioriteit is — dit is belangrijke UX voor gebruikers.
Fout 4: het maken van een nieuw thema bij elke build. Als ThemeData wordt gemaakt binnen de build-methode, creëert elke herbouw van de widget een nieuw thema-object, waardoor de optimalisatie van InheritedWidget wordt verbroken. Oplossing: plaats ThemeData in een statisch veld of const-constructor buiten de build.
Conclusie: correcte thematisering vereist een gecentraliseerde aanpak. Plaats ThemeData in constanten, gebruik kleurenschema's uit het thema en definieer altijd beide thema's — licht en donker.
Veelgestelde vragen
ThemeData — de configuratiegegevens (kleuren, lettertypen, stijlen). Theme — InheritedWidget die ThemeData doorgeeft in de widgetboom. Theme.of(context) retourneert de ThemeData die de dichtstbijzijnde Theme verspreidt in de huidige context.
Beheer themeMode in MaterialApp via de applicatiestatus. Wijzig de status van ThemeMode.light naar ThemeMode.dark en Flutter herbouwt de hele boom met het nieuwe thema. Gebruik AnimatedTheme voor vloeiende animatie.
ColorScheme.fromSeed — Material 3-methode die één basiskleur (seedColor) ontvangt en een volledig harmonieus palet genereert: primary, secondary, tertiary, surface, error en hun on-varianten. Maakt het mogelijk een samenhangend kleurenschema te krijgen uit één merk kleur.
Via TextTheme in ThemeData: specificeer TextStyle met fontFamily voor elk niveau. Gebruik voor Google Fonts het pakket google_fonts en geef fontFamily rechtstreeks door in TextTheme. Voor lokale lettertypen — voeg ze toe via pubspec.yaml in de sectie fonts.
Ja. Wikkel het scherm in een Theme met overschreven gegevens via copyWith. Alle onderliggende widgets binnen deze Theme krijgen de gewijzigde stijlen, terwijl de rest van de applicatie het originele thema behoudt. Dit creëert geen extra overhead.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook