Lesson 12 / 25

Material 3 Theming and Dark Mode

ThemeData, ColorScheme.fromSeed and Theme.of.

One source of visual truth

MaterialApp takes a theme, an optional darkTheme and a themeMode (system, light or dark). Material 3 is the default in recent Flutter versions. ColorScheme.fromSeed generates a full, accessible palette (primary, secondary, surface, error and their "on" colours) from one seed colour, with brightness: Brightness.dark for the dark variant. Read values in widgets with Theme.of(context).colorScheme and Theme.of(context).textTheme rather than hard-coding colours and font sizes. Component themes such as filledButtonTheme or inputDecorationTheme customise widgets globally, and a nested Theme widget overrides a subtree.

Light and dark from one seed

App-level theme and reading it in a widget.

MaterialApp(
  theme: ThemeData(
    colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF0F766E)),
  ),
  darkTheme: ThemeData(
    colorScheme: ColorScheme.fromSeed(
      seedColor: const Color(0xFF0F766E),
      brightness: Brightness.dark,
    ),
  ),
  themeMode: ThemeMode.system, // follow the device setting
  home: const HomePage(),
);

// inside any widget
final scheme = Theme.of(context).colorScheme;
Text('Total', style: Theme.of(context).textTheme.titleLarge?.copyWith(
  color: scheme.primary,
));

Never hard-code Colors.white for text

Use scheme.onSurface, scheme.onPrimary and similar; hard-coded colours are the usual reason dark mode looks broken.

Quick check: What does ColorScheme.fromSeed do?

  • Downloads a theme from the internet
  • Generates a complete, harmonious colour scheme from one seed colour
  • Picks random colours each launch
  • Only sets the AppBar colour
Answer

Generates a complete, harmonious colour scheme from one seed colour — It derives tonal palettes for every Material colour role.