tabBarTheme static method

TabBarTheme tabBarTheme({
  1. required ColorScheme colorScheme,
  2. TextStyle? labelStyle,
  3. Color? labelColor,
  4. Color? unselectedLabelColor,
  5. TabBarIndicatorSize? indicatorSize,
  6. double? indicatorWeight,
  7. double? indicatorTopRadius,
  8. Color? indicatorColor,
  9. TextStyle? unselectedLabelStyle,
  10. Color? dividerColor,
  11. bool? useTintedInteraction,
  12. bool? useMaterial3,
})

An opinionated TabBarTheme theme.

Contrary to the other opinionated static FlexSubThemes sub-theme function, this one is only a sub-set of the original and does not do or contain any feature shortcuts.

The FlexColorScheme.toTheme needs some of the properties, like fore- and background colors used here, for other component theme definitions as well and has already computed them once, so they are reused here.

Implementation

static TabBarTheme tabBarTheme({
  /// Typically the same [ColorScheme] that is also used for your [ThemeData].
  required final ColorScheme colorScheme,

  /// Overrides the default value for [TabBar.labelStyle].
  final TextStyle? labelStyle,

  /// Overrides the default value for [TabBar.labelColor].
  final Color? labelColor,

  /// Overrides the default value for [TabBar.unselectedLabelColor].
  final Color? unselectedLabelColor,

  /// Overrides the default value for [TabBar.indicatorSize].
  final TabBarIndicatorSize? indicatorSize,

  /// The thickness of the underline border indicator on the [TabBar].
  ///
  /// If not defined, defaults to 2 in M2 and to 3 in M3.
  final double? indicatorWeight,

  /// The top left and right corner radius of the underline border
  /// indicator on the [TabBar].
  ///
  /// If not defined, defaults to 0 in M2 and to 3 in M3.
  final double? indicatorTopRadius,

  /// Overrides the default value for [TabBar.indicatorColor].
  final Color? indicatorColor,

  /// Overrides the default value for [TabBar.unselectedLabelStyle].
  final TextStyle? unselectedLabelStyle,

  /// The color of the divider.
  ///
  /// If null and [useMaterial3] is true, [TabBarTheme.dividerColor]
  /// color is used. If that is null and [useMaterial3] is true,
  /// [ColorScheme.surfaceVariant] will be used,
  /// otherwise divider will not be drawn.
  final Color? dividerColor,

  /// Defines if the theme uses tinted interaction effects.
  ///
  /// If undefined, defaults to false.
  final bool? useTintedInteraction,

  /// 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;
  final bool tintInteract = useTintedInteraction ?? false;
  final double weight = indicatorWeight ?? (useM3 ? 3 : 2);
  final double radius = indicatorTopRadius ?? (useM3 ? 3 : 0);

  final Decoration indicator = UnderlineTabIndicator(
    borderRadius: useM3 || indicatorWeight != null
        ? BorderRadius.only(
            topLeft: Radius.circular(radius),
            topRight: Radius.circular(radius),
          )
        : null,
    borderSide: BorderSide(
      width: weight,
      color: indicatorColor ??
          (useM3 ? colorScheme.primary : colorScheme.onSurface),
    ),
  );

  final Color overlayBase =
      labelColor ?? (useM3 ? colorScheme.primary : colorScheme.onPrimary);

  // Only make a custom overlay when we have settings that require it.
  final bool useCustomOverlay = tintInteract ||
      (useM3 && labelColor != colorScheme.primary && labelColor != null) ||
      (!useM3 && labelColor != colorScheme.onPrimary && labelColor != null);

  return TabBarTheme(
    labelStyle: labelStyle,
    labelColor: labelColor,
    unselectedLabelStyle: unselectedLabelStyle,
    unselectedLabelColor: unselectedLabelColor,
    //
    indicatorSize: indicatorSize ??
        (useM3 ? TabBarIndicatorSize.label : TabBarIndicatorSize.tab),
    indicatorColor: indicatorColor,
    indicator: (indicatorWeight != null || indicatorTopRadius != null)
        ? indicator
        : null,
    dividerColor: dividerColor,
    //
    overlayColor: useCustomOverlay
        ? MaterialStateProperty.resolveWith((Set<MaterialState> states) {
            if (states.contains(MaterialState.selected)) {
              if (states.contains(MaterialState.hovered)) {
                return overlayBase.withAlpha(kAlphaHovered);
              }
              if (states.contains(MaterialState.focused)) {
                return overlayBase.withAlpha(kAlphaFocused);
              }
              if (states.contains(MaterialState.pressed)) {
                return overlayBase.withAlpha(kAlphaPressed);
              }
              return null;
            }
            if (states.contains(MaterialState.hovered)) {
              if (tintInteract) return overlayBase.withAlpha(kAlphaHovered);
              return colorScheme.onSurface.withAlpha(kAlphaHovered);
            }
            if (states.contains(MaterialState.focused)) {
              if (tintInteract) return overlayBase.withAlpha(kAlphaFocused);
              return colorScheme.onSurface.withAlpha(kAlphaFocused);
            }
            if (states.contains(MaterialState.pressed)) {
              if (tintInteract) return overlayBase.withAlpha(kAlphaPressed);
              return overlayBase.withAlpha(kAlphaPressed);
            }
            return null;
          })
        : null,
  );
}