ThemeData.from constructor Null safety

ThemeData.from(
  1. {required ColorScheme colorScheme,
  2. TextTheme? textTheme,
  3. bool? useMaterial3}
)

Create a ThemeData based on the colors in the given colorScheme and text styles of the optional textTheme.

The colorScheme can not be null.

If colorScheme.brightness is Brightness.dark then ThemeData.applyElevationOverlayColor will be set to true to support the Material dark theme method for indicating elevation by applying a semi-transparent onSurface color on top of the surface color.

This is the recommended method to theme your application. As we move forward we will be converting all the widget implementations to only use colors or colors derived from those in ColorScheme.

This example will set up an application to use the baseline Material Design light and dark themes.
MaterialApp(
  theme: ThemeData.from(colorScheme: const ColorScheme.light()),
  darkTheme: ThemeData.from(colorScheme: const ColorScheme.dark()),
)

See material.io/design/color/ for more discussion on how to pick the right colors.

Implementation

factory ThemeData.from({
  required ColorScheme colorScheme,
  TextTheme? textTheme,
  bool? useMaterial3,
}) {
  final bool isDark = colorScheme.brightness == Brightness.dark;

  // For surfaces that use primary color in light themes and surface color in dark
  final Color primarySurfaceColor = isDark ? colorScheme.surface : colorScheme.primary;
  final Color onPrimarySurfaceColor = isDark ? colorScheme.onSurface : colorScheme.onPrimary;

  return ThemeData(
    colorScheme: colorScheme,
    brightness: colorScheme.brightness,
    primaryColor: primarySurfaceColor,
    primaryColorBrightness: ThemeData.estimateBrightnessForColor(primarySurfaceColor),
    canvasColor: colorScheme.background,
    accentColor: colorScheme.secondary,
    accentColorBrightness: ThemeData.estimateBrightnessForColor(colorScheme.secondary),
    scaffoldBackgroundColor: colorScheme.background,
    bottomAppBarColor: colorScheme.surface,
    cardColor: colorScheme.surface,
    dividerColor: colorScheme.onSurface.withOpacity(0.12),
    backgroundColor: colorScheme.background,
    dialogBackgroundColor: colorScheme.background,
    indicatorColor: onPrimarySurfaceColor,
    errorColor: colorScheme.error,
    textTheme: textTheme,
    applyElevationOverlayColor: isDark,
    useMaterial3: useMaterial3,
  );
}