FlexColorScheme.dark constructor

FlexColorScheme.dark({
  1. FlexSchemeColor? colors,
  2. FlexScheme? scheme,
  3. int usedColors = 4,
  4. FlexSurface surfaceStyle = FlexSurface.material,
  5. FlexAppBarStyle appBarStyle = FlexAppBarStyle.material,
  6. FlexTabBarStyle tabBarStyle = FlexTabBarStyle.forAppBar,
  7. double appBarElevation = 0,
  8. double? bottomAppBarElevation,
  9. Color? surface,
  10. Color? background,
  11. Color? scaffoldBackground,
  12. Color? onPrimary,
  13. Color? onSecondary,
  14. Color? onSurface,
  15. Color? onBackground,
  16. Color? onError,
  17. bool darkIsTrueBlack = false,
  18. bool swapColors = false,
  19. bool tooltipsMatchBackground = false,
  20. bool transparentStatusBar = true,
  21. VisualDensity? visualDensity,
  22. String? fontFamily,
  23. TargetPlatform? platform,
  24. Typography? typography,
})

Creates a dark FlexColorScheme based on the given FlexSchemeColor.

The only required property is FlexSchemeColor, which can be created with just one color property using the factory FlexSchemeColor.from, more detailed color themes can also be defined.

Implementation

factory FlexColorScheme.dark({
  /// The [FlexSchemeColor] that we will create the dark [FlexColorScheme]
  /// from.
  ///
  /// You can use predefined [FlexSchemeColor] values from
  /// [FlexColor.schemes] map or define your own colors with
  /// [FlexSchemeColor] or [FlexSchemeColor.from].
  ///
  /// For using built-in color schemes, the convenience shortcut to select
  /// it with the `scheme` property is recommended and leaving `colors`
  /// undefined. If both are specified the scheme colors defined by `colors`
  /// are used. If both are null then `scheme` defaults to
  /// [FlexScheme.material], thus defining the resulting scheme.
  FlexSchemeColor? colors,

  /// A shortcut to use one of the built-in color schemes defined by
  /// enum [FlexScheme].
  ///
  /// Just give it one of the enum values to use the scheme, like eg.
  /// [FlexScheme.mandyRed].
  ///
  /// To create custom color schemes use the `colors` property. If both
  /// `colors`and `scheme` are specified, the scheme defined by
  /// `colors` is used. If both are null, then `scheme` defaults to
  /// [FlexScheme.material], thus defining the resulting scheme.
  FlexScheme? scheme,

  /// The number of the four main scheme colors to be used of the ones
  /// passed in via the required colors [FlexSchemeColor] property.
  ///
  /// This is a convenience property that allows you to vary which colors to
  /// use of the primary, secondary and variant colors included in `colors` in
  /// [FlexSchemeColor]. The integer number corresponds to using:
  /// 1 = Only the primary color
  /// 2 = Primary + Secondary colors
  /// 3 = Primary + Primary variant + Secondary colors
  /// 4 = Primary + Primary variant + Secondary + Secondary variant colors
  /// By default the value is 4 and all main scheme colors in
  /// [FlexSchemeColor] are used.
  ///
  /// When the value is 1, the result is the same as if we would have
  /// created the colors with [FlexSchemeColor.from] by only giving it the
  /// required primary color. With 2, it is equivalent to as if we would have
  /// given it only the primary and secondary colors, and so on.
  /// This property makes it possible to simulate and change the resulting
  /// [FlexColorScheme] to as if you would have specified 1, 2, 3 or 4 of
  /// the colors. If your used [FlexColorScheme] `colors` was actually created
  /// with [FlexSchemeColor.from] with only the primary color defined, then
  /// changing the value from 4 to 3, 2 or 1, will all produce the same
  /// effective scheme as the computed values will be the same as the
  /// [FlexSchemeColor.from] is using to compute any main missing scheme
  /// color values.
  int usedColors = 4,

  /// Defines which surface style to use.
  ///
  /// Defaults to [FlexSurface.material] which results in Flutter
  /// standard [ColorScheme.dark] surface colors, which follows the
  /// default color scheme in the Material Design
  /// guide for dark theme found here:
  /// https://material.io/design/color/dark-theme.html#ui-application
  ///
  /// If values for [surface], [background] ot [scaffoldBackground] are
  /// provided, they are used instead of values that would be assigned based
  /// on the selected and provided [FlexSurface] style.
  FlexSurface surfaceStyle = FlexSurface.material,

  /// The app bar background theme style.
  ///
  /// Defaults to [FlexAppBarStyle.material] which produces the same results
  /// as a Flutter standard dark [ThemeData.from] by tying the app bar color
  /// to the surface color.
  FlexAppBarStyle appBarStyle = FlexAppBarStyle.material,

  /// Select preferred style for the default TabBarTheme.
  ///
  /// By default the TabBarTheme is made to fit with the style of the AppBar,
  /// via default value [FlexTabBarStyle.forAppBar].
  ///
  /// When setting this to [FlexTabBarStyle.forBackground], it will default
  /// to a theme that uses the color scheme and fits on background color,
  /// which typically also on works surface and scaffoldBackground color.
  /// This TabBarTheme style is useful if you primarily intended to use the
  /// TabBar in a Scaffold, Dialog, Drawer or Side panel on their background
  /// colors.
  FlexTabBarStyle tabBarStyle = FlexTabBarStyle.forAppBar,

  /// The themed elevation for the app bar.
  ///
  /// Default to 0. The 0 elevation is an iOs style
  /// influenced opinionated choice, but it can easily be adjusted for the
  /// theme with this property.
  double appBarElevation = 0,

  /// The themed elevation for the bottom app bar.
  ///
  /// If null, defaults to the value given to the `appBarElevation` elevation.
  double? bottomAppBarElevation,

  /// The background color for widgets like Card, BottomAppBar and dialogs.
  ///
  /// If null, the color is determined by [FlexSurface] `surfaceStyle`.
  Color? surface,

  /// A color that typically appears behind scrollable content.
  ///
  /// The color is applied to ThemeData `canvasColor` and`backgroundColor`,
  /// it is used eg in menu drawer.
  ///
  /// If null, the color is determined by [FlexSurface] `surfaceStyle`.
  Color? background,

  /// The color of the scaffold background.
  ///
  /// If null the color is defined by [FlexSurface] `surfaceStyle`.
  Color? scaffoldBackground,

  /// A color that is clearly legible when drawn on [primary] color.
  ///
  /// If null, the on color is derived from the brightness of the [primary]
  /// color, and will be be black if it is light and white if it is dark.
  Color? onPrimary,

  /// A color that is clearly legible when drawn on [secondary] color.
  ///
  /// If null, the on color is derived from the brightness of the [secondary]
  /// color, and will be be black if it is light and white if it is dark.
  Color? onSecondary,

  /// A color that is clearly legible when drawn on [surface] color.
  ///
  /// If null, the on color is derived from the brightness of the [surface]
  /// color, and will be be black if it is light and white if it is dark.
  Color? onSurface,

  /// A color that is clearly legible when drawn on [background] color, it is
  /// also used as on color for [scaffoldBackground].
  ///
  /// If null, the on color is derived from the brightness of the [background]
  /// color, and will be be black if it is light and white if it is dark.
  Color? onBackground,

  /// A color that is clearly legible when drawn on [error].
  ///
  /// If null, the on color is derived from the brightness of the [error]
  /// color, and will be be black if it is light and white if it is dark.
  Color? onError,

  /// Makes the dark theme even darker.
  ///
  /// Mostly surfaces will become fully black, but surfaces may in
  /// primary blend modes still use a hint of surface color for a slight
  /// off black mode when primary blended surface are used.
  bool darkIsTrueBlack = false,

  /// If true, this will swap primary and variant colors with their
  /// secondary counter parts.
  ///
  /// This flag can be set to true, if you want to make a theme where
  /// your primary and secondary colors are swapped.
  ///
  /// This feature is useful if you want to do this with the pre-defined
  /// schemes or with computed dark themes from light theme. If you are
  /// explicitly defining all your theme colors you can of course define
  /// them as desired. Even if you do that, this feature will still swap
  /// whatever colors you defined for primary and secondary. You can offer this
  /// feature as an easy end user modifiable theme option if you like.
  bool swapColors = false,

  /// Tooltips background color will match the brightness of the theme's
  /// background color.
  ///
  /// By default Flutter's Material tooltips uses a theme where the tooltip
  /// background color brightness is inverted in relation to the overall
  /// theme's background color. FlexColorScheme allows you to use a single
  /// toggle to invert this. Light tooltips on light background is e.g. the
  /// default style on Windows Desktop. You can use this toggle to use this
  /// style, or as a means to create a platform adaptive
  /// tooltip style, where the Material/Flutter style is used on devices and
  /// Web, but the inverted scheme would be used on desktop platforms.
  ///
  /// Defaults to false, uses same background style as Material and Flutter.
  bool tooltipsMatchBackground = false,

  /// When set to `true`, it makes the status bar on Android the same color as
  /// the rest of the AppBar. Defaults to true.
  ///
  /// When true, the AppBar in Android mimics the look of one-toned AppBar's
  /// typically used on iOS. Set to `false`, to revert back and use
  /// Android's default two-toned look. If true the status bar area is
  /// actually also transparent so that if the app bar is also translucent,
  /// content that scrolls behind it, is also visible behind the status
  /// bar area.
  ///
  /// You may need to fully restart the app and even rebuild for changes to
  /// this setting to take effect on Android devices and emulators.
  bool transparentStatusBar = true,

  /// Same property as in [ThemeData] factory, it is just passed along to it.
  ///
  /// Included for convenience to avoid a copyWith if it needs to be changed.
  VisualDensity? visualDensity,

  /// Same property as in [ThemeData] factory, it is just passed along to it.
  ///
  /// Included for convenience to avoid a copyWith if it needs to be changed.
  String? fontFamily,

  /// Same property as in [ThemeData] factory, it is just passed along to it.
  ///
  /// Included for convenience to avoid a copyWith if it needs to be changed.
  /// Defaults to [defaultTargetPlatform].
  TargetPlatform? platform,

  /// Same property as in [ThemeData] factory.
  ///
  /// Included for convenience to avoid a copyWith if it needs to be changed.
  /// Default value deviates from the Flutter standard that uses the old
  /// [Typography.material2014], in favor of newer [Typography.material2018]
  /// as default typography if one is not provided.
  ///
  /// Never mix different [Typography] in light and dark theme mode. If you
  /// do, lerping between dark and light theme mode will fail due Flutter SDK
  /// not being able to handle the use case. If you use a default light or dark
  /// Flutter ThemeData() and a FlexColorScheme.toTheme() ThemeData for the
  /// other one, you must set either the default ThemeData to
  /// [Typography.material2018] OR the [FlexColorScheme.typography] to
  /// [Typography.material2014] to avoid this issue. It is not generally
  /// recommended to create you light and dark theme mode data with
  /// different methods. If you use FlexColorScheme, DO use it for both the
  /// light and dark theme mode.
  Typography? typography,
}) {
  // DARK: Check valid inputs
  assert(usedColors >= 1 && usedColors <= 4, 'usedColors must be 1 to 4.');
  assert(appBarElevation >= 0.0, 'AppBar elevation must be >= 0.');
  assert(bottomAppBarElevation == null || bottomAppBarElevation >= 0.0,
      'Bottom AppBar elevation must be null or must be >= 0.');
  // Fallback value for scheme is default material scheme.
  scheme ??= FlexScheme.material;
  // If colors was null, we used the scheme based value.
  colors ??= FlexColor.schemesWithCustom[scheme]!.dark;
  // If bottomAppBarElevation is null default to appBarElevation.
  bottomAppBarElevation ??= appBarElevation;

  // Get the actual used color scheme that depends on usedColors and scheme.
  final FlexSchemeColor effectiveColors =
      FlexSchemeColor.effective(colors, usedColors, swapColors: swapColors);

  // If [surfaceStyle] is [FlexSurface.custom] then the returned surfaceColors
  // will be same as [FlexSurface.material], to get a different result
  // surface colors must be been passed in to FlexColorScheme.dark. It is
  // up to the implementation using [FlexSurface.custom] to do so.
  // The returned surfaceColors will NEVER be null, it always has colors.
  final FlexSchemeSurfaceColors surfaceColors = FlexSchemeSurfaceColors.from(
    brightness: Brightness.dark,
    surfaceStyle: surfaceStyle,
    primary: effectiveColors.primary,
  );

  // For the on colors we pass in the primary, secondary and surface colors to
  // calculate onColors for. If some onColors were passed in, we give
  // that value to it, if it was not null it will be used instead of the
  // calculated on color.
  final FlexSchemeOnColors onColorsTheme = FlexSchemeOnColors.from(
    primary: effectiveColors.primary,
    secondary: effectiveColors.secondary,
    surface: surface ?? surfaceColors.surface,
    background: background ?? surfaceColors.background,
    error: effectiveColors.error ?? FlexColor.materialDarkError,
    onPrimary: onPrimary,
    onSecondary: onSecondary,
    onSurface: onSurface,
    onBackground: onBackground,
    onError: onError,
  );

  // Determine effective surface color.
  // Surface is used e.g. by Card and bottom appbar and in this
  // implementation also by dialogs.
  // If true black, we make a darker than normal surface. If not
  // true black, we use provided surface color, or computed one.
  Color effectiveSurfaceColor;
  if (darkIsTrueBlack) {
    effectiveSurfaceColor =
        surface?.darken(6) ?? surfaceColors.surface.darken(6);
  } else {
    effectiveSurfaceColor = surface ?? surfaceColors.surface;
  }

  // Determine effective background color.
  // Used e.g. by drawer, nav rail, side menu and bottom bar.
  // If true black, we use darker then normal background. If not true black,
  // we use provided background color, or computed one.
  Color effectiveBackgroundColor;
  if (darkIsTrueBlack) {
    effectiveBackgroundColor =
        background?.darken(8) ?? surfaceColors.background.darken(8);
  } else {
    effectiveBackgroundColor = background ?? surfaceColors.background;
  }

  // Get the effective app bar color based on the style
  Color? effectiveAppBarColor;
  switch (appBarStyle) {
    case FlexAppBarStyle.primary:
      effectiveAppBarColor = effectiveColors.primary;
      break;
    case FlexAppBarStyle.material:
      effectiveAppBarColor = darkIsTrueBlack
          ? const Color(0xFF000000)
          : FlexColor.materialDarkSurface;
      break;
    case FlexAppBarStyle.background:
      effectiveAppBarColor = effectiveBackgroundColor;
      break;
    case FlexAppBarStyle.surface:
      effectiveAppBarColor = effectiveSurfaceColor;
      break;
    case FlexAppBarStyle.custom:
      effectiveAppBarColor = effectiveColors.appBarColor ??
          (darkIsTrueBlack
              ? const Color(0xFF000000)
              : FlexColor.materialDarkSurface);
      break;
  }

  // Return a DARK FlexColorScheme based on above values, we use
  // fallbacks in the constructor too, they are required for the custom
  // settings if some provided values were null.
  return FlexColorScheme(
    // Primary color for the application
    primary: effectiveColors.primary,
    // The primary variant should generally be a bit darker color than
    // primary, preferably of a color like it or darker hue of primary.
    // If no value was provided we make a hue that is 10% darker.
    primaryVariant: effectiveColors.primaryVariant,
    // The secondary color for the application. If you do not want
    // to use it set it to the same color as primary. For a subtle
    // one color based theme you can use a hue of the primary.
    // This creates one that is 5% darker than primary, if not given.
    secondary: effectiveColors.secondary,
    // The secondary variant should generally be a bit darker color than
    // secondary, preferably of a color like it or darker hue of secondary.
    // We us any provided value, if none darken the secondary and if no
    // secondary was provided we darken the primary 15%
    secondaryVariant: effectiveColors.secondaryVariant,
    // Surface is used e.g. by Card and bottom appbar and in this
    // implementation also by dialogs.
    surface: effectiveSurfaceColor,
    // Used e.g. by drawer, nav rail, side menu and bottom bar.
    background: effectiveBackgroundColor,
    // If darkIsTrueBlack is set, we use black as default scaffold background,
    // otherwise provided values are used, if null then the default is 8%
    // of Primary color on dark grey #121212.
    // Fallback from theme, to custom value to material default const.
    scaffoldBackground: darkIsTrueBlack
        ? const Color(0xFF000000)
        : scaffoldBackground ?? surfaceColors.scaffoldBackground,
    // Set app bar background to effective background color.
    appBarBackground: effectiveAppBarColor,
    // Effective error color and null fallback.
    error: effectiveColors.error ?? FlexColor.materialDarkError,
    // The "on" colors will get defaults later by [toTheme] getter if they do
    // not have values here, so we do not need to check them here.
    onPrimary: onColorsTheme.onPrimary,
    onSecondary: onColorsTheme.onSecondary,
    onSurface: onColorsTheme.onSurface,
    onBackground: onColorsTheme.onBackground,
    onError: onColorsTheme.onError,
    tabBarStyle: tabBarStyle,
    appBarElevation: appBarElevation,
    bottomAppBarElevation: bottomAppBarElevation,
    // This is dark theme factory, so brightness is always dark
    brightness: Brightness.dark,
    tooltipsMatchBackground: tooltipsMatchBackground,
    transparentStatusBar: transparentStatusBar,
    // Visual density, fontFamily, platform and typography values are just
    // passed as is along to FlexColorScheme and from there to Theme factory.
    // They are just included as a way to include them also when needed
    // in FlexColorScheme based themes.
    visualDensity: visualDensity,
    fontFamily: fontFamily,
    platform: platform,
    typography: typography,
  );
}