switchTheme static method
SwitchThemeData
switchTheme({
- required ColorScheme colorScheme,
- SchemeColor? baseSchemeColor,
- SchemeColor? thumbSchemeColor,
- bool? thumbFixedSize,
- double? splashRadius,
- bool? unselectedIsColored,
- bool? useTintedInteraction,
- bool? useTintedDisable,
- bool? useMaterial3,
An opinionated SwitchThemeData theme.
Requires a ColorScheme in colorscheme
. The color scheme would
typically be equal the color scheme also used to define the color scheme
for your app theme.
The splashRadius is not used by FlexColorScheme sub-themes.
Implementation
static SwitchThemeData switchTheme({
/// Typically the same `ColorScheme` that is also used for your `ThemeData`.
required final ColorScheme colorScheme,
/// Selects which color from the passed in colorScheme to use as the main
/// color for the switch.
///
/// All colors in the color scheme are not good choices, but some work well.
///
/// If not defined, [colorScheme.primary] will be used. This is more in-line
/// with M3 design, but applied to M2 switch. The M3 color design
/// specification for the secondary color, is a poor choice for toggles and
/// switches, if such colors are used in M2 mode, primary color works
/// better.
final SchemeColor? baseSchemeColor,
/// Selects which color from the passed in colorScheme to use as the thumb
/// color for the switch.
///
/// All colors in the color scheme are not good choices, but some work well.
///
/// If not defined, [colorScheme.primary] will be used in M2 mode.
/// This is more in-line
/// with M3 design, but applied to M2 switch. The M3 color design
/// specification for the secondary color, is a poor choice for toggles and
/// switches, if such colors are used in M2 mode, primary color works
/// better.
///
/// If not defined, defaults to:
///
/// - If useMaterial3 is false [baseSchemeColor].
/// - If useMaterial3 is true [SchemeColor.primaryContainer].
final SchemeColor? thumbSchemeColor,
/// Set to true to keep the [Switch] thumb size fixed.
///
/// When true the [Switch] thumb size does not change from small size when
/// OFF, to a larger size when ON. This makes the Material-3 Switch even
/// more similar to the iOS style Switch.
///
/// This setting only applies to the Material-3 mode, it has no effect in
/// Material-2 mode.
///
/// If undefined, defaults to false.
final bool? thumbFixedSize,
/// The splash radius of the circular Material ink response.
///
/// If null, default via SDK defaults to [kRadialReactionRadius] = 20.
final double? splashRadius,
/// Defines if unselected [Switch] is also themed to be [baseSchemeColor].
///
/// If false, it is grey like in Flutter SDK.
///
/// If undefined, defaults to false.
final bool? unselectedIsColored,
/// Defines if the theme uses tinted interaction effects.
///
/// If undefined, defaults to false.
final bool? useTintedInteraction,
/// Defines if the theme uses tinted disabled color.
///
/// If undefined, defaults to false.
final bool? useTintedDisable,
/// A temporary flag used to opt-in to Material 3 features.
///
/// If set to true, the theme will use Material3 default styles when
/// properties are undefined, if false defaults will use FlexColorScheme's
/// own opinionated default values.
///
/// The M2/M3 defaults will only be used for properties that are not
/// defined, if defined they keep their defined values.
///
/// If undefined, defaults to false.
final bool? useMaterial3,
}) {
final bool useM3 = useMaterial3 ?? false;
// Get colorScheme brightness.
final bool isLight = colorScheme.brightness == Brightness.light;
// Get selected base color, and its pair, defaults to primary and onPrimary.
final Color baseColor =
schemeColor(baseSchemeColor ?? SchemeColor.primary, colorScheme);
final Color onBaseColor =
schemeColorPair(baseSchemeColor ?? SchemeColor.primary, colorScheme);
final bool unselectedColored = unselectedIsColored ?? false;
final bool tintInteract = useTintedInteraction ?? false;
final bool tintDisable = useTintedDisable ?? false;
// Using these tinted overlay variable in all themes for ease of
// reasoning and duplication.
final Color overlay = colorScheme.surface;
final Color tint = baseColor;
final double factor = _tintAlphaFactor(tint, colorScheme.brightness, true);
// Get selected thumb color, and its pair, defaults to
// M2: primary and onPrimary.
// M3: primaryContainer and onPrimaryContainer
final Color thumbColor = schemeColor(
thumbSchemeColor ??
(useM3
? SchemeColor.primaryContainer
: baseSchemeColor ?? SchemeColor.primary),
colorScheme);
// Material 2 style Switch
if (!useM3) {
return SwitchThemeData(
splashRadius: splashRadius,
thumbColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
if (states.contains(MaterialState.selected)) {
if (tintDisable) {
return tintedDisable(colorScheme.onSurface, baseColor);
}
return isLight ? Colors.grey.shade400 : Colors.grey.shade800;
}
if (tintDisable) {
return tintedDisable(colorScheme.onSurface, baseColor)
.withAlpha(kAlphaLowDisabled);
}
return isLight ? Colors.grey.shade400 : Colors.grey.shade800;
}
if (states.contains(MaterialState.selected)) {
return thumbColor;
}
return isLight ? Colors.grey.shade50 : Colors.grey.shade400;
},
),
trackColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
if (tintDisable) {
return tintedDisable(colorScheme.onSurface, baseColor)
.withAlpha(kAlphaVeryLowDisabled);
}
return isLight ? Colors.black12 : Colors.white10;
}
if (states.contains(MaterialState.selected)) {
return baseColor.withAlpha(
isLight ? kAlphaM2SwitchTrackLight : kAlphaM2SwitchTrackDark);
}
// Custom themed color on track when not selected
if (unselectedColored) {
return baseColor.withAlpha(isLight
? kAlphaM2SwitchUnselectTrackLight
: kAlphaM2SwitchUnselectTrackDark);
}
// This is SDK default, yes that value is hard coded in SDK too.
return isLight ? kSwitchM2LightTrackColor : Colors.white30;
},
),
overlayColor:
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
if (states.contains(MaterialState.pressed)) {
if (tintInteract) return tintedPressed(overlay, tint, factor);
return baseColor.withAlpha(kAlphaPressed);
}
if (states.contains(MaterialState.hovered)) {
if (tintInteract) return tintedHovered(overlay, tint, factor);
return baseColor.withAlpha(kAlphaHovered);
}
if (states.contains(MaterialState.focused)) {
if (tintInteract) return tintedFocused(overlay, tint, factor);
return baseColor.withAlpha(kAlphaFocused);
}
return null;
}
if (states.contains(MaterialState.pressed)) {
if (tintInteract) return tintedPressed(overlay, tint, factor);
return colorScheme.onSurface.withAlpha(kAlphaPressed);
}
if (states.contains(MaterialState.hovered)) {
if (tintInteract) return tintedHovered(overlay, tint, factor);
return colorScheme.onSurface.withAlpha(kAlphaHovered);
}
if (states.contains(MaterialState.focused)) {
if (tintInteract) return tintedFocused(overlay, tint, factor);
return colorScheme.onSurface.withAlpha(kAlphaFocused);
}
return null;
}),
);
}
// Material 3 style Switch
else {
return SwitchThemeData(
splashRadius: splashRadius,
thumbIcon: thumbFixedSize ?? false
? MaterialStateProperty.resolveWith<Icon?>(
(Set<MaterialState> states) {
return const Icon(Icons.minimize, color: Colors.transparent);
})
: null,
thumbColor:
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
if (states.contains(MaterialState.selected)) {
return colorScheme.surface;
}
if (tintDisable) {
return tintedDisable(colorScheme.onSurface, baseColor);
}
return colorScheme.onSurface.withAlpha(kAlphaDisabled);
}
if (states.contains(MaterialState.selected)) {
if (states.contains(MaterialState.pressed)) {
return thumbColor;
}
if (states.contains(MaterialState.hovered)) {
return thumbColor;
}
if (states.contains(MaterialState.focused)) {
return thumbColor;
}
return onBaseColor;
}
if (states.contains(MaterialState.pressed)) {
return colorScheme.onSurfaceVariant;
}
if (states.contains(MaterialState.hovered)) {
return colorScheme.onSurfaceVariant;
}
if (states.contains(MaterialState.focused)) {
return colorScheme.onSurfaceVariant;
}
return colorScheme.outline;
}),
trackColor:
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
if (states.contains(MaterialState.selected)) {
if (tintDisable) {
return tintedDisable(colorScheme.onSurface, baseColor);
}
return colorScheme.onSurface.withAlpha(kAlphaVeryLowDisabled);
}
return colorScheme.surfaceVariant.withAlpha(kAlphaVeryLowDisabled);
}
if (states.contains(MaterialState.selected)) {
if (states.contains(MaterialState.pressed)) {
return baseColor;
}
if (states.contains(MaterialState.hovered)) {
return baseColor;
}
if (states.contains(MaterialState.focused)) {
return baseColor;
}
return baseColor;
}
if (states.contains(MaterialState.pressed)) {
return unselectedColored
? baseColor.withAlpha(isLight
? kAlphaM3SwitchUnselectTrackLight
: kAlphaM3SwitchUnselectTrackDark)
: colorScheme.surfaceVariant;
}
if (states.contains(MaterialState.hovered)) {
return unselectedColored
? baseColor.withAlpha(isLight
? kAlphaM3SwitchUnselectTrackLight
: kAlphaM3SwitchUnselectTrackDark)
: colorScheme.surfaceVariant;
}
if (states.contains(MaterialState.focused)) {
return unselectedColored
? baseColor.withAlpha(isLight
? kAlphaM3SwitchUnselectTrackLight
: kAlphaM3SwitchUnselectTrackDark)
: colorScheme.surfaceVariant;
}
return unselectedColored
? baseColor.withAlpha(isLight
? kAlphaM3SwitchUnselectTrackLight
: kAlphaM3SwitchUnselectTrackDark)
: colorScheme.surfaceVariant;
}),
trackOutlineColor:
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return Colors.transparent;
}
if (states.contains(MaterialState.disabled)) {
if (tintDisable) {
return tintedDisable(colorScheme.onSurface, baseColor);
}
return colorScheme.onSurface.withAlpha(kAlphaVeryLowDisabled);
}
return colorScheme.outline;
}),
overlayColor:
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
if (states.contains(MaterialState.pressed)) {
if (tintInteract) return tintedPressed(overlay, tint, factor);
return baseColor.withAlpha(kAlphaPressed);
}
if (states.contains(MaterialState.hovered)) {
if (tintInteract) return tintedHovered(overlay, tint, factor);
return baseColor.withAlpha(kAlphaHovered);
}
if (states.contains(MaterialState.focused)) {
if (tintInteract) return tintedFocused(overlay, tint, factor);
return baseColor.withAlpha(kAlphaFocused);
}
return null;
}
if (states.contains(MaterialState.pressed)) {
if (tintInteract) return tintedPressed(overlay, tint, factor);
return colorScheme.onSurface.withAlpha(kAlphaPressed);
}
if (states.contains(MaterialState.hovered)) {
if (tintInteract) return tintedHovered(overlay, tint, factor);
return colorScheme.onSurface.withAlpha(kAlphaHovered);
}
if (states.contains(MaterialState.focused)) {
if (tintInteract) return tintedFocused(overlay, tint, factor);
return colorScheme.onSurface.withAlpha(kAlphaFocused);
}
return null;
}),
);
}
}