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:
- FlexThemeData static extension on
ThemeData
. - 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 customFlexColorScheme
based theme, from color definitions you already have in a standardColorScheme
. This property also exists in the default constructor. If you usecolorScheme
the colors in the providedcolorScheme
will override any values you have given in thescheme
orcolors
properties. -
The direct color properties available in the constructors, e.g.
primary
,primaryContainer
, etc., that are all named like the same color properties inColorScheme
or e.g.scaffoldBackground
inThemeData
, will override any corresponding color values that would be set via any other color affecting properties provided viascheme
,colors
and also the ones in acolorScheme
. The direct color properties provide an alternative way to override individual colors values in built-inscheme
,colors
or providedcolorScheme
. Not all color properties in aColorScheme
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 effectiveColorScheme
from the input colors. The integer number corresponds to using:- Only the primary color
- Primary & Secondary colors
- Primary + container & Secondary colors
- Primary + container & Secondary + container
- Primary + container & Secondary + container & tertiary colors
- Primary + container & Secondary + container & tertiary + container
- 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 settinginputColors
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 resultingColorScheme
andThemeData
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 resultingColorScheme
andThemeData
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 customizedTonalPalette
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 flagswapOnMaterial3
. When defined to be true, the scheme will benefit if thesecondary
andtertiary
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 theirswapOnMaterial3
set to true. If this flag is false, it may mean that itsFlexSchemeColor
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, setswapLegacyOnMaterial3
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 keepswapOnMaterial3
false for more prominent colors on secondaries.This color swap has higher priority than
swapColor
, using it will always happen on the effective result ofswapLegacyOnMaterial3
anduseMaterial3
, and value ofswapOnMaterial3
in currently used built-in schemeFlexSchemeColor
.If a custom
colorScheme
is passed in, or any of the direct color propertiessecondary
,secondaryContainer
,tertiary
ortertiaryContainer
, then it is assumed a custom scheme or overrides, are being used and theswapLegacyOnMaterial3
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 setuseMaterial3
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:
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:
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 andThemeData.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 usingTypography.material2018
in Material-3 mode. -
When using FlexColorScheme and
ThemeData.useMaterial3
is false and sub themes are not used, then default typography isTypography.material2018
. Note that if FlexColorScheme is not used at all, and yourThemeData
hasThemeData.useMaterial3
false, then Flutter defaults to using very old poorTypography.material2014
. In such cases consider defining your typography manually toTypography.material2018
or why not evenTypography.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 customtypography
toFlexColorScheme
orFlexThemeData
, 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 byFlexColorScheme
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
andThemeData.primaryTextTheme
. The strength of the blend is affected by the generalblendLevel
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 correspondingColorScheme
color property's color into its onColors. IfblendOnColors
is false, theblendOnLevel
setting only affectsonSurface
,onBackGround
,onPrimaryContainer
,onSecondaryContainer
onTertiaryContainer
andonErrorContainer
. IfblendOnColors
is true, it also impactsonPrimary
,onSecondary
,onTertiary
andonError
. -
blendOnColors: (true/false). Set to true to enable
blendOnLevel
based onColor blending also ononPrimary
,onSecondary
andonTertiary
colors. UseblendOnLevel
value to in FlexColorScheme themes to also blend in each correspondingColorScheme
color property's color into its onColors. IfblendOnColors
is false, theblendOnLevel
setting only affectsonSurface
,onBackGround
,onPrimaryContainer
,onSecondaryContainer
onTertiaryContainer
andonErrorContainer
. IfblendOnColors
is true, it also impactsonPrimary
,onSecondary
,onTertiary
andonError
. -
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 true
value. 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:
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.
- buttonTheme. This theme controls the old deprecated Material buttons theme. The buttons are already deprecated and will be removed in the next version of Flutter SDK. This theme is also going away in Flutter and will be deprecated in the next version of FlexColorScheme too.
- bottomNavigationBar used to create the component theme for the BottomNavigationBar widget.
- bottomSheetTheme used to create the component theme for the BottomSheet widget.
- cardTheme used to create the component theme for the Card widget.
- checkboxTheme used to create the component theme for the Checkbox widget, also applies to check boxes used by the CheckBoxListTile.
- chipTheme used to create the component theme for the Chip widget and related chips like InputChip, ChoiceChip, FilterChip and ActionChip.
- dialogTheme used to create the component theme for Dialog widgets.
- elevatedButtonTheme used to create the component theme for the ElevatedButton widget.
- floatingActionButtonTheme used to create the component theme for the FloatingActionButton widget.
- inputDecorationTheme used to create the component theme for InputDecoration configuration that describes the style of TextField and InputDecorator.
- navigationBarTheme used to create the component theme for the Material-3 NavigationBar widget.
- navigationRailTheme used to create the component theme for the NavigationRail widget.
- outlinedButtonTheme used to create the component theme for the OutlinedButton widget.
- popupMenuTheme used to create the component theme for the PopupMenuButton widget.
- radioTheme used to create the component theme for the Radio widget.
- sliderTheme used to create the component theme for the Slider widget.
- snackBarTheme used to create the component theme for the SnackBar widget.
- switchTheme used to create the component theme for the Switch widget.
- textButtonTheme used to create the component theme for the TextButton widget.
- timePickerTheme used to create the component theme for the TimePickerDialog widget.
- toggleButtonsTheme used to create the component theme for the ToggleButtons widget.
- tooltipTheme used to create the component theme for the Tooltip widget.
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
.