LogoFlexColorScheme

API Guide

The API reference documentation for FlexColorScheme generated from code document comments is very thorough. It should cover most questions you might have. An overview of key APIs is presented below. It may be extended with more information and examples in future updates. These updates will be influenced by what questions users raise about the API.

You can create FlexColorScheme based ThemeData objects using two different APIs:

  1. FlexThemeData static extension on ThemeData.
  2. FlexColorScheme.toTheme class and method.

FlexThemeData#

API reference: FlexThemeData

There are separate APIs for creating the light theme mode, and dark theme mode ThemeData:

Example: FlexThemeData

Using this API is very familiar, it looks a lot like ThemeData.light and dark, but with Flex prepended. They, of course, have a lot of additional properties, but the basic usage is simple.

  class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
      title: 'API Guide',
      theme: FlexThemeData.light(scheme: FlexScheme.mandyRed),
      darkTheme: FlexThemeData.dark(scheme: FlexScheme.mandyRed),
      themeMode: ThemeMode.system,
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );

The FlexThemeData is a static extension on ThemeData to define a FlexColorScheme object and return the ThemeData object defined by its instance, using its FlexColorScheme.toTheme method, all done in one step with a more compact API.

Using e.g. FlexThemeData.light() is a bit shorter than FlexColorScheme.light().toTheme, and it may also feel more familiar since you get a ThemeData object directly, that you can use just like any other ThemeData object produced by Flutter's different built-in ThemeData factory constructors.

FlexColorScheme#

API reference: FlexColorScheme

The original way to create FlexColorScheme based ThemeData objects is to use the package namesake FlexColorScheme class and then use its toTheme method to make and return the ThemeData object specified by your immutable FlexColorScheme configuration.

Usually you should not use the raw default FlexColorScheme() constructor to create your FlexColorScheme object, you should prefer using its two factories:

These factories are used to make FlexColorScheme based ThemeData definitions for light and dark theme mode respectively. They offer many additional parameters over the raw default constructor, that are used to create more nuanced and computed ColorScheme definitions, that are then used by the created ThemeData.

Here is how you would use them to define identical themes as the above ones, where we used FlexThemeData.light and .dark:

Example: FlexColorScheme

Making ThemeData with FlexColorScheme's namesake class, is a bit more verbose, but it does the same thing. Strictly speaking it is FlexThemeData that does the same thing, since it uses FlexColorScheme.toTheme under the hood.

  class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
      title: 'API Guide',
      theme: FlexColorScheme.light(scheme: FlexScheme.mandyRed).toTheme,
      darkTheme: FlexColorScheme.dark(scheme: FlexScheme.mandyRed).toTheme,
      themeMode: ThemeMode.system,
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );

The FlexColorScheme.light().toTheme and FlexThemeData.light(), and its dark counterparts, all have the same properties and are interchangeable. The light and dark parameters differ slightly, due to a few different features for light and dark themes.

Common Properties#

Important properties for FlexColorScheme.light() and FlexThemeData.light(), as well as for FlexColorScheme.dark() and FlexThemeData.dark(), are presented below. The examples use FlexThemeData, but they are identical when using FlexColorScheme.

The two most commonly used properties to define used colors in the produced ThemeData are:

  • scheme a FlexScheme enum value used to select which predefined color scheme to use for the theme.

  • colors a FlexSchemeColor object used to define custom colors to be used when creating the theme.

If you specify both scheme and colors, the custom colors in colors, have higher precedence and are used, and the scheme property is ignored. If you specify neither, then scheme defaults to FlexScheme.material.

You can also create a custom FlexColorScheme based theme, from a Flutter standard ColorScheme object, by providing it a colorScheme.

  • colorScheme a ColorScheme object used to create a custom FlexColorScheme based theme, from color definitions you already have in a standard ColorScheme. This property also exists in the default constructor. If you use colorScheme the colors in the provided colorScheme will override any values you have given in the scheme or colors properties.

  • The direct color properties available in the constructors, e.g. primary, primaryContainer, etc., that are all named like the same color properties in ColorScheme or e.g. scaffoldBackground in ThemeData, will override any corresponding color values that would be set via any other color affecting properties provided via scheme, colors and also the ones in a colorScheme. The direct color properties provide an alternative way to override individual colors values in built-in scheme, colors or provided colorScheme. Not all color properties in a ColorScheme are available as direct color property values, but commonly used ones are.

FlexColorScheme has shortcut enum properties that you can use to quickly adjust the theme design for your AppBar and TabBar.

  • appBarStyle a FlexAppBarStyle enum value used to define the themed color of the AppBar background color.

  • tabBarStyle a FlexTabBarStyle enum value used to select preferred style for used TabBarTheme theme.

  • appBarOpacity a double value, can also be used to define the opacity of the AppBar background.

An interesting and unique feature of FlexColorScheme is its capability to automatically create color schemes and resulting themes that blend in the primary color into different surfaces. You can vary this blending depending on the surface type and use different blend strengths. This feature is only available via the factory constructors and their ThemeData extensions, not via the default raw FlexColorscheme() constructor. To use the surface blending features use the properties surfaceMode and blendLevel.

  • surfaceMode a FlexSurfaceMode enum value used to select the mode for blending in primary color into surface, background, scaffoldBackground and dialogBackground colors.

  • blendLevel, integer value, sets the blend level strength used by the used surfaceMode. The blend level is the integer decimal value of the alpha value used in the alpha blend function. It mixes one color with another, by using alpha opacity value in the color of a surface put on top of another surface with opaque color, and returns the result as one opaque color.

You can also use properties like inputColors, swapColors and e.g. useMaterial3ErrorColors to modify the main input colors, before they are used to create the effective ColorScheme used in produced ThemeData.

  • inputColors integer value that defines the number of the six main scheme colors to be used when creating the effective ColorScheme. A convenience property that allows you to vary which colors to use of input primary, secondary and tertiary colors and their container colors, when FlexSchemeColor creates its effective ColorScheme from the input colors. The integer number corresponds to using:

    1. Only the primary color
    2. Primary & Secondary colors
    3. Primary + container & Secondary colors
    4. Primary + container & Secondary + container
    5. Primary + container & Secondary + container & tertiary colors
    6. Primary + container & Secondary + container & tertiary + container
    7. Primary + Secondary + Tertiary

    Computed color values are used by the ones being left out, the computed colors are derived from included ones. You can create a theme that uses only different shades and tones derived from the input primary color, by setting inputColors to 1. Defaults to 6, always using all 6 main input colors if they are defined.

  • swapColors boolean value. When true, the primary and primaryContainer colors will be swapped with their secondary counterparts. Set this flag to true, if you want to make a theme where your primary and secondary colors are swapped, compared to how they are defined in the given input color properties or selected pre-defined color scheme.

    This is useful if you want to do this with the pre-defined schemes for more theme options. If you are explicitly defining all your theme colors, you can define them in any desired order. Even if you do that, this feature, if used, will still swap whatever colors you defined for primary and secondary. You can also offer this feature as an easy end user modifiable theme option. Another usage possibility is to set swapColors to true only for the dark mode and use your color scheme primary and secondary the other way around in dark mode.

  • useMaterial3 boolean value. Defaults to false. A flag used to opt in to new SDK Material-3 features. Same property as in ThemeData, see API doc or Flutter API docs for more information.

  • useMaterial3ErrorColors boolean value. Set it to true to use the new Material-3 error colors. If useMaterial3ErrorColors is false, the resulting ColorScheme and ThemeData will use Material-2 default error colors or error colors as defined by the built-in color schemes. Thus, using the same error colors as in FlexColorScheme versions before version 5.

    If useMaterial3ErrorColors is true, the resulting ColorScheme and ThemeData will use the Material-3 design guide error colors. Key color seed generated ColorSchemes always uses the Material-3 design guide error colors, or error colors from its customized TonalPalette generation setup. Defaults to false.

    The new M3 error colors are generally nicer looking. If your theme is using red color shades, you can try both options to see which option works better with your theme's red colors. That would be the red error color option that is more distinguishable from your main red theme colors.

  • swapLegacyOnMaterial3 boolean value. Set it to true, to automatically swap secondary and tertiary colors on built-in color schemes, when useMaterial3 is true, if the scheme benefits from it to better match the Material-3 color system design intent.

    Starting with FlexColorScheme version 6.1.0, built-in color schemes, defined via FlexSchemeColor, have a flag swapOnMaterial3. When defined to be true, the scheme will benefit if the secondary and tertiary colors, including their containers, are swapped when using Material-3. Most FlexColorScheme color schemes were designed with M2 usage in mind, before M3 existed. They may often have their swapOnMaterial3 set to true. If this flag is false, it may mean that its FlexSchemeColor was designed for M3 or that it won't benefit from swapping its secondary and tertiary colors. In the Scheme Reference, you can see which schemes have the flag defined to true.

    Using a seed-generated color scheme based on built-in FlexSchemeColor colors is another way to make them suitable for the M3 Color system. However, in some cases, the secondary color in their design may not be in-line with the M3 color system design intent, especially if you use the config that also uses the hue from the secondary color to make tonal palettes for it. In some legacy FlexSchemeColor color designs, this can be fixed if we swap the secondary and tertiary colors.

    To make FlexSchemeColor designs color designs that benefit from it automatically swap secondary and tertiary colors when useMaterial3 is set to true, set swapLegacyOnMaterial3 to true. It defaults to false, for backward compatibility, but it is recommended to turn it on when using Material-3 and its color system. If you use seeded color schemes with Material-2, useMaterial3 flag is false, then it may be preferable to keep swapOnMaterial3 false for more prominent colors on secondaries.

    This color swap has higher priority than swapColor, using it will always happen on the effective result of swapLegacyOnMaterial3 and useMaterial3, and value of swapOnMaterial3 in currently used built-in scheme FlexSchemeColor.

    If a custom colorScheme is passed in, or any of the direct color properties secondary, secondaryContainer, tertiary or tertiaryContainer, then it is assumed a custom scheme or overrides, are being used and the swapLegacyOnMaterial3 setting does nothing.

    The Themes Playground app defaults to setting swapLegacyOnMaterial3 to ON (true), but allows you to turn it OFF. Defaults to false, for backwards compatibility, but prefer setting it to true if you also set useMaterial3 to true.

Example: Demo of Common Properties

In this example, we use many of the above-discussed properties:

theme: FlexThemeData.light(
  scheme: FlexScheme.flutterDash,
  usedColors: 4,
  surfaceMode: FlexSurfaceMode.highScaffoldLowSurface,
  blendLevel: 20,
  appBarStyle: FlexAppBarStyle.background,
  appBarOpacity: 0.95,
  tabBarStyle: FlexTabBarStyle.forBackground,
  swapColors: true,
  useMaterial3ErrorColors: true,
),
darkTheme: FlexThemeData.dark(
  scheme: FlexScheme.flutterDash,
  usedColors: 4,
  surfaceMode: FlexSurfaceMode.highScaffoldLowSurface,
  blendLevel: 15,
  appBarStyle: FlexAppBarStyle.background,
  appBarOpacity: 0.90,
  tabBarStyle: FlexTabBarStyle.forBackground,
  useMaterial3ErrorColors: true,
),

This produces an app with a theme looking like this, when we try it in the Copy Playground app:

API basic 1   API basic 2   API basic 3   API basic 4
The Copy Playground theme presentation app, with above FlexThemeData setup.

Use FlexColorScheme or FlexThemeData?#

When should you use FlexColorScheme.light().toTheme instead of FlexThemeData.light()?

If all you need is the ThemeData object, then you may prefer using FlexThemeData.light() due to its shorter and more familiar syntax.

However, if you need access to the ColorScheme that will be made by toTheme when it creates ThemeData, you may prefer first defining a FlexColorScheme object. You can then use the FlexColorScheme.toScheme method to get the ColorScheme it will use in its created ThemeData. You can use this ColorScheme the get access to the identical ColorScheme, regardless of what properties you used to define and generate it with in your FlexColorScheme configuration.

Example: Using ColorScheme from FlexColorScheme.toScheme

You often need access to FlexColorScheme's ColorScheme if you make custom component themes in order to use theme matching colors in them.

// A function to make custom ThemeData using FlexColorScheme
// and a custom ToggleButtonsThemeData component theme.
ThemeData myLightTheme({
}) {
  // We need to use the ColorScheme defined by the ThemeData that
  // FlexColorScheme will create based on our configuration in our
  // custom component theme. We first create the `FlexColorScheme` object:
  final FlexColorScheme flexScheme = FlexColorScheme.light(
    scheme: FlexScheme.flutterDash,
    surfaceMode: FlexSurfaceMode.highScaffoldLowSurface,
    blendLevel: 10,
    appBarStyle: FlexAppBarStyle.background,
    appBarOpacity: 0.95,
    tabBarStyle: FlexTabBarStyle.forBackground,
  );
  // Then get the `ColorScheme` defined by our FlexColorScheme configuration,
  // using its `toScheme` method.
  final ColorScheme colorScheme = flexScheme.toScheme;
  // We can the return the `ThemeData` from our `FlexColorScheme`, with
  // our custom component theme added to it, where its customizations uses
  // color that the `ColorScheme` in the return `ThemeData` also gets.
  return flexScheme.toTheme.copyWith(
    // Add our custom toggle buttons component theme.
    toggleButtonsTheme: toggleButtonsTheme(colorScheme),
  );
}

// ToggleButtons theme.
ToggleButtonsThemeData toggleButtonsTheme(ColorScheme colorScheme) =>
    ToggleButtonsThemeData(
      selectedColor: colorScheme.onPrimary,
      color: colorScheme.primary.withOpacity(0.85),
      fillColor: colorScheme.primary.withOpacity(0.85),
      hoverColor: colorScheme.primary.withOpacity(0.2),
      focusColor: colorScheme.primary.withOpacity(0.3),
      borderWidth: 1.5,
      borderColor: colorScheme.primary,
      selectedBorderColor: colorScheme.primary,
      borderRadius: BorderRadius.circular(20),
    );

Above you could also create the entire ThemeData from the FlexColorScheme instance flexScheme above. Extract its ColorScheme and use it to make the component theme toggleButtonsTheme, and then use copyWith on the already created ThemeData that you return as ThemeData. Both work, the above should, in theory, be marginally more resource efficient, but it probably does not matter in practice.

Generated ColorScheme#

Flutter has ColorScheme.fromSeed to make delightful Material-3 specification based computational ColorSchemes. With FlexColorScheme you can use the identical algorithm that is used by ColorScheme.fromSeed. You can also completely customize it, while still be producing a ColorScheme that adheres to the Material-3 color system, but primes the color generation engine a bit differently.

Since ColorScheme.fromSeed only uses one single color as seed color, and always the same ColorScheme generation parameters, the amount of variation it provides is a bit limited, and the results also tend to be soft pastel color oriented. As we get used to them, they will all start looking quite similar.

By priming the FlexColorScheme customizable ColorScheme generation differently, you can create more varied results that are not so repetitive of what has already been seen before, even if it still uses the same M3 color system design principle, based on tonal palettes. You can read and see a brief explanation in the Themes Playground guide about what the tonal palettes are.

To make a key color seed generated ColorScheme with FlexColorscheme, using its effective input primary color as the seed key, pass in a default FlexKeyColors() to the keyColors property.

With this default you get a computed ColorScheme that is identical to the one you would have gotten if you used ColorScheme.fromSeed with the effective input primary color from your FlexColorScheme.

With FlexKeyColors you can also use the secondary and tertiary colors in your FlexColorScheme as input color keys, that are then used when generating the secondary and tertiary tonal palettes respectively. Please see the API documentation for more information about additional parameters in FlexKeyColors.

Starting from version 6.0.0, FlexColorScheme no longer directly depends on package Material Color Utilities package, which is also used by Flutter SDK. Instead, it uses package FlexSeedScheme that depends on it. As a part of this change classes FlexTones, FlexTonalPalette and FlexCorePalette where moved into the package FlexSeedScheme. FlexColorScheme still exports these classes. If you were using them directly before, you can still do so without adding the FlexSeedScheme package.

API reference: FlexKeyColors

By specifying a FlexTones() configuration for tones in FlexColorScheme you can further adjust how the ColorScheme generation algorithm computes the primary, secondary and tertiary tonal palettes. The properties Chroma and MinChroma, prepended with primary, secondary and tertiary for each tonal palette from corresponding key color, adjust how the algorithm uses the input colors when it generates the tonal palettes from the key colors.

See API reference for details:

You can also modify which tone in the generated tonal palettes is mapped to what ColorScheme color, within the limits that it only allows mapping tones from each tonal palette to the colors in the ColorScheme that in Material-3 color system design use the tonal palette in question, but you can change used tone to be different from the Material-3 guide specification and values used in Flutter SDK.

To make custom FlexTones(), prefer using the theme mode appropriate constructor FlexTones.light() or FlexTones.dark() that have defaults that create the setup for the Material-3 spec used in Flutter ColorScheme.fromSeed, but where each property can be changed from the default as preferred.

There are other predefined FlexTones configurations in addition to the default Material-3 guide spec matching one. You can use them as they are, or as examples of how to create your own custom tones configurations. Made a great one? Please share it in the FlexColorScheme GitHub repository's show and tell discussions forum. Maybe we can add it as another predefined option.

See API reference for more details on FlexTones:

  • Class FlexTones

  • Light mode default value factory FlexTones.light, default and the same as Flutter SDK M3 setup for a light ColorScheme.

  • Dark mode default value factory FlexTones.dark, default and same as Flutter SDK M3 setup for a dark ColorScheme.

  • Material-3 spec tones constructor FlexTones.material, default and same as Flutter SDK M3 setup.

  • Vivid color tones constructor FlexTones.vivid, more vivid colors, or at least closer in chroma to the used seed key color, as it uses chroma from all key colors as given.

  • Vivid surfaces tones constructor FlexTones.vividSurfaces, like vivid, but with double the chroma in each surface tonal palette.

  • Vivid background tones constructor FlexTones.vividBackground, like vividSurfaces, but with tone mapping for surface and background color swapped.

  • Soft tones constructor FlexTones.soft, softer and earthier tones than M3 FlexTones.material.

  • High contrast tones constructor FlexTones.highContrast, can be used for more color-accessible themes. It offers more contrast between colors.

  • Ultra contrast tones constructor FlexTones.ultraContrast, a tonal palette extraction setup that results in a very high contrast version of produced ColorsSchemes, it is less colorful and more focused a pure white or pure dark backgrounds and foreground colors.

  • Jolly tones constructor FlexTones.jolly, creates a tonal palette extraction setup that results in a more jolly and colorful ColorsSchemes.

  • One hue tones constructor FlexTones.oneHue, Create a M3 tonal palette tones extraction, but with no hue rotation from primary if no ARGB key color is provided for tertiary palette. This setup will if only one seed color is used, produce a more chromatic color set than FlexTones.material. Since it does not rotate hue from primary to get hue for tertiary, it will also create a color scheme using tonal palettes that are based on the same hue, but with different chroma. In simple terms, all colors are shades of the provided key color to seed the tonal palettes. We can get a nice one hue toned theme with this configuration.

  • FlexTones.candyPop for a high contrast, candy popping theme. It has tone 100, which is white surface and background in light mode and very dark tone 6, dark mode. This FlexTones uses the paletteType extended via FlexPaletteType.extended, for additional tone fidelity.

  • FlexTones.chroma for a theme where the chroma in each seed color is used as is with any min limitation. Chroma in passed in color can even be zero, producing a greyscale tonal palette as the palette. It has tone 100, which is white surface and background in light mode and very dark tone 6, dark mode. This FlexTones also uses the paletteType extended via FlexPaletteType.extended, for additional tone fidelity.

Example: FlexColorScheme with keyColors and Tones

Here we use a key color generated ColorScheme, while using otherwise same property values as in the previous example.

theme: FlexThemeData.light(
  scheme: FlexScheme.flutterDash,
  usedColors: 4,
  surfaceMode: FlexSurfaceMode.highScaffoldLowSurface,
  blendLevel: 20,
  appBarStyle: FlexAppBarStyle.background,
  appBarOpacity: 0.95,
  tabBarStyle: FlexTabBarStyle.forBackground,
  swapColors: true,
  keyColors: const FlexKeyColors(
    useSecondary: true,
    useTertiary: true,
  ),
  tones: FlexTones.vivid(Brightness.light),
),
darkTheme: FlexThemeData.dark(
  scheme: FlexScheme.flutterDash,
  usedColors: 4,
  surfaceMode: FlexSurfaceMode.highScaffoldLowSurface,
  blendLevel: 15,
  appBarStyle: FlexAppBarStyle.background,
  appBarOpacity: 0.90,
  tabBarStyle: FlexTabBarStyle.forBackground,
  keyColors: const FlexKeyColors(
    useSecondary: true,
    useTertiary: true,
  ),
  tones: FlexTones.vivid(Brightness.dark),
),

Above we used one of the predefined custom tone setups called FlexTones.vivid. Making custom tones is simple, the code for this predefined example is:

static FlexTones vivid(Brightness brightness) =>
    brightness == Brightness.light
        ? const FlexTones.light(
            primaryTone: 30,
            primaryChroma: null,
            secondaryChroma: null,
            tertiaryChroma: null,
            primaryMinChroma: 50,
          )
        : const FlexTones.dark(
            onPrimaryTone: 10,
            primaryContainerTone: 20,
            onErrorContainerTone: 90,
            primaryChroma: null,
            secondaryChroma: null,
            tertiaryChroma: null,
            primaryMinChroma: 50,
          );

When we try the above FlexThemeData config, again in the Copy Playground app, we get an application with this theme:

API keyColor 5   API keyColor 6   API keyColor 7   API keyColor 8
The Copy Playground theme presentation app, with the above FlexThemeData setup, using keyColors generated ColorScheme with custom tones.

Component Themes#

A more opinionated theme and style can be created by passing in a default FlexSubThemesData() constructor to the FlexColorScheme or FlexThemeData, property subThemesData.

By default, the component themes take inspiration from the Material-3 design guide specification and uses its values as defaults when it is possible to do so in Flutter SDK theming, still having its Material-2 design theming limitations.

The component themes can be configured further by configuring a large number of properties in FlexSubThemesData, that is passed into subThemesData. A commonly used feature is to adjust the default corner border radius on all sub-themes for widgets that support it.

Other opinionated changes include a more flat design, and features like primary tinted hover, focus, highlight and splash colors, among other things.

For full list of component theme configuration options and some other related theme-modifying properties, please see the API docs for FlexSubThemesData.

API reference: FlexSubThemesData.

FlexSubThemesData#

In addition to all the actual component theme configuration parameters, the FlexSubThemesData configuration has a few extra settings that are also used to control the behavior of the opinionated overall theme.

  • useTextTheme: (true/false/null). Determines if Material-3 TextTheme and Typography is used. When opting in on using the sub-theming, this flag controls if the TextTheme use the new Material-3 Typography.material2021 as specified in the Material-3 Design Guide.

    • If not defined, and ThemeData.useMaterial3 is true, then it defaults to true. If not defined and ThemeData.useMaterial3 is false, then it defaults to false.

    • This toggle works as an override toggle for using Typography.material2021 in Material-2 mode and for using Typography.material2018 in Material-3 mode.

    • When using FlexColorScheme and ThemeData.useMaterial3 is false and sub themes are not used, then default typography is Typography.material2018. Note that if FlexColorScheme is not used at all, and your ThemeData has ThemeData.useMaterial3 false, then Flutter defaults to using very old poor Typography.material2014. In such cases consider defining your typography manually to Typography.material2018 or why not even Typography.material2021. FlexColorScheme fully supports using any custom TextTheme and fonts, just like ThemeData. You apply and use them just as you would with ThemeData. This text theme is just a custom predefined TextTheme. If you specify a custom typography to FlexColorScheme or FlexThemeData, this property has no impact on used typography.

    • This property was originally used in FlexColorScheme to opt-in on using a custom text theme defined internally by FlexColorScheme to look like the typography and text theme used in Material-3, before such a text theme and typography existed in Flutter. When Flutter started providing M3 text theme and typography, this property was converted into toggle to opt in and out of using the text theme. Typically, you do not want to opt-out of it, but in M2 mode you may want to opt-in and set it to true.

  • blendTextTheme: (true/false). Used blend primary color into text themes for both ThemeData.textTheme and ThemeData.primaryTextTheme. The strength of the blend is affected by the general blendLevel of used FlexColorScheme. This feature does not look so good if you need to put text on a completely different colored container than the background color. If this is your use case, consider setting it to false.

  • blendOnLevel: (int: 0). Sets the blend level strength of container color, used in its onColor. Use blendOnLevel value to in FlexColorScheme themes to also blend in each corresponding ColorScheme color property's color into its onColors. If blendOnColors is false, the blendOnLevel setting only affects onSurface, onBackGround, onPrimaryContainer, onSecondaryContainer onTertiaryContainer and onErrorContainer. If blendOnColors is true, it also impacts onPrimary, onSecondary, onTertiary and onError.

  • blendOnColors: (true/false). Set to true to enable blendOnLevel based onColor blending also on onPrimary, onSecondary and onTertiary colors. Use blendOnLevel value to in FlexColorScheme themes to also blend in each corresponding ColorScheme color property's color into its onColors. If blendOnColors is false, the blendOnLevel setting only affects onSurface, onBackGround, onPrimaryContainer, onSecondaryContainer onTertiaryContainer and onErrorContainer. If blendOnColors is true, it also impacts onPrimary, onSecondary, onTertiary and onError.

  • interactionEffects: (true/false). Flag used to enable color tinted hover, focus, highlight, selected, pressed and splash interaction state effects. The standard Flutter colors in both M2 and M3 mode for hover, focus, highlight, selected, pressed and splash state effects often look grey. They typically use surface or onSurface color with opacity. Often this is white or black with different opacity levels. This is not very color expressive and sometimes even look out of character in M3 mode.

  • tintedDisabledControls: (true/false). Set to true to make disabled controls use a slight color tint of their own main enabled color on their disabled state. Enabling this feature makes the theme even more color expressive than Material-3 is by default.

Example: FlexColorScheme with SubThemes

A very practical use case of FlexSubThemes, is to customize the default border radius on all Flutter UI components and elements, that supports border radius either via ShapeBorder or BorderRadiusGeometry. This can be done with a single property, the defaultRadius.

In this example, we enable the opinionated component themes and decided we want all our components that have adjustable border radius, to use 12 dp as their border radius. We also turned off the M3 text theme and set onColors in light mode to use blend level 20, and no blends on onPrimary, onSecondary, onTertiary and onError. In dark mode we wanted a stronger blend on the onColors, and we wanted in on all onColors and left blendOnColors to its default truevalue. Otherwise, we use the same property values as in the previous example.

theme: FlexThemeData.light(
  scheme: FlexScheme.flutterDash,
  usedColors: 4,
  surfaceMode: FlexSurfaceMode.highScaffoldLowSurface,
  blendLevel: 20,
  appBarStyle: FlexAppBarStyle.background,
  appBarOpacity: 0.95,
  tabBarStyle: FlexTabBarStyle.forBackground,
  swapColors: true,
  subThemesData: const FlexSubThemesData(
    blendOnLevel: 20,
    blendOnColors: false,
    useTextTheme: false,
    defaultRadius: 12.0,
  ),
  keyColors: const FlexKeyColors(
    useSecondary: true,
    useTertiary: true,
  ),
  tones: FlexTones.vivid(Brightness.light),
),
darkTheme: FlexThemeData.dark(
  scheme: FlexScheme.flutterDash,
  usedColors: 4,
  surfaceMode: FlexSurfaceMode.highScaffoldLowSurface,
  blendLevel: 15,
  appBarStyle: FlexAppBarStyle.background,
  appBarOpacity: 0.90,
  tabBarStyle: FlexTabBarStyle.forBackground,
  subThemesData: const FlexSubThemesData(
    blendOnLevel: 30,
    useTextTheme: false,
    defaultRadius: 12.0,
  ),
  keyColors: const FlexKeyColors(
    useSecondary: true,
    useTertiary: true,
  ),
  tones: FlexTones.vivid(Brightness.dark),
),

When we try the above FlexThemeData config, again in the Copy Playground app, we get an application with this themed design:

API sub 9   API sub 10   API sub 11   API sub 12
The Copy Playground theme presentation app, with above FlexThemeData setup using component subThemesData and global border defaultRadius of 12 dp.

FlexSubThemes#

When you opt in on using the component themes, the FlexColorScheme.toTheme method uses the passed in FlexSubThemesData configuration data object, that is passed in via FlexColorScheme.subThemesData, to create the component themes using the properties provided.

In some cases, typically for older core related "legacy" component theme cases, the component themes are created directly in the toTheme method. However, in most cases separate static sub-theme helper functions from the FlexSubThemes class are used. Component themes that are currently only defined directly in the toTheme method, will be moved into the FlexSubThemes class as well in a future update.

These FlexSubThemes component themes are currently available and used via their static helper functions, when toTheme creates ThemeData:

API reference: FlexSubThemes.

You can also use these static component theme helpers without using FlexColorScheme to define custom components themes, or even without using FlexColorScheme at all. You can further modify the component theme helpers' produced results by using their copyWith method.

These helpers may sometimes be simpler to use than the raw component theme constructors. You can also study them to see how some component theme that interests you is defined.

Theme Extensions#

In version 5.1.0, FlexColorScheme added direct support for theme extensions to its API. You use it the same way as you use it with ThemeData. The default example, "The Hot Reload Playground" includes a simple demonstration of how to use it. In this example, it is only used to add a single extra theme color, that is used to give the heading a color based on this theme extension color. With theme extensions, you can add as many colors and other theme properties as you need, and you can add multiple different ThemeExtension subclasses as well.

/// A theme Extension example with a single custom brand color property.
class BrandTheme extends ThemeExtension<BrandTheme> {
  const BrandTheme({
    this.brandColor,
  });
  final Color? brandColor;

  // You must override the copyWith method.
  @override
  BrandTheme copyWith({
    Color? brandColor,
  }) =>
      BrandTheme(
        brandColor: brandColor ?? this.brandColor,
      );

  // You must override the lerp method.
  @override
  BrandTheme lerp(ThemeExtension<BrandTheme>? other, double t) {
    if (other is! BrandTheme) {
      return this;
    }
    return BrandTheme(
      brandColor: Color.lerp(brandColor, other.brandColor, t),
    );
  }
}

// Custom const theme with our brand color in light mode.
const BrandTheme lightBrandTheme = BrandTheme(
  brandColor: Color.fromARGB(255, 8, 79, 71),
);

// Custom const theme with our brand color in dark mode.
const BrandTheme darkBrandTheme = BrandTheme(
  brandColor: Color.fromARGB(255, 167, 227, 218),
);

The lightBrandTheme is then added to our light theme via FlexThemeData.light, like so:

class _DemoAppState extends State<DemoApp> {
  ThemeMode themeMode = ThemeMode.system;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: FlexThemeData.light(
        ...
        // Add all our custom theme extensions, in this case we only have one.
        extensions: <ThemeExtension<dynamic>>{
          lightBrandTheme,
        },
      ),
   ...
   );

The same is done with the darkBrandTheme color in darkTheme with FlexThemeData.dark.