Zentralisiere Farben und Typografie in ThemeData, erzeuge mit ColorScheme.fromSeed eine Material-3-Palette und biete mühelos einen Dark Mode an.
Diese Lektion in Kodokon öffnenAufzuhören, Widget für Widget zu stylen, ist ein professioneller Meilenstein: ThemeData zentralisiert Farben, Typografie und Formen für die gesamte App. Mit Material 3 (seit Flutter 3.16 standardmäßig aktiv) beginnt alles beim ColorScheme: ColorScheme.fromSeed leitet aus einer einzigen Seed-Farbe eine vollständige, harmonische und barrierefreie Palette ab.
import 'package:flutter/material.dart';
void main() {
runApp(const ShopApp());
}
class ShopApp extends StatelessWidget {
const ShopApp({super.key});
@override
Widget build(BuildContext context) {
const seed = Colors.teal;
return MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: seed,
),
),
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: seed,
brightness: Brightness.dark,
),
),
themeMode: ThemeMode.system,
home: Scaffold(
appBar: AppBar(title: const Text('Shop')),
body: const Center(child: Text('Welcome')),
),
);
}
}Erfinde in deinen Widgets nichts neu: Lies das umgebende Theme mit Theme.of(context). Das colorScheme stellt semantische Rollen bereit (primary, onPrimary, primaryContainer, surface und so weiter), und textTheme stellt benannte Stile bereit (titleMedium, bodyLarge und so weiter). Ein so geschriebenes Widget passt sich automatisch an das helle wie an das dunkle Theme an.
import 'package:flutter/material.dart';
class PriceTag extends StatelessWidget {
const PriceTag({super.key, required this.price});
final double price;
@override
Widget build(BuildContext context) {
final colors = Theme.of(context).colorScheme;
final text = Theme.of(context).textTheme;
return Container(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
decoration: BoxDecoration(
color: colors.primaryContainer,
borderRadius: BorderRadius.circular(8),
),
child: Text(
'$price €',
style: text.titleMedium?.copyWith(
color: colors.onPrimaryContainer,
),
),
);
}
}Um weiterzugehen, konfiguriere die Komponenten-Themes: Jede Widget-Familie (App-Bars, Buttons, Eingabefelder) akzeptiert in ThemeData ein eigenes Theme. Du legst das Padding deiner Buttons oder die Zentrierung deiner Titel einmal fest, und jede Instanz erbt es, ohne einen einzigen lokalen Stil.
import 'package:flutter/material.dart';
final ThemeData appTheme = ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.teal,
),
appBarTheme: const AppBarTheme(
centerTitle: true,
elevation: 0,
),
filledButtonTheme: FilledButtonThemeData(
style: FilledButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 24,
vertical: 12,
),
),
),
);