BaseTabBar class

BaseTabBar with iOS 26 Liquid Glass Dynamic Material and Material 3 support

Features iOS 26 Liquid Glass Dynamic Material with:

  • Transparency with optical clarity zones for tab navigation
  • Environmental reflections and adaptive opacity
  • Dynamic interaction states with real-time responsiveness
  • Enhanced haptic feedback for tab selection
  • Unified design language across platforms

Material 3 Integration:

  • TabBar with Material 3 design tokens
  • Semantic ColorScheme usage with adaptive colors
  • Modern elevation system with surface tinting
  • Enhanced accessibility with semantic navigation

Cross-platform support:

  • CupertinoTabBar with Liquid Glass enhancement by cupertino
  • Material 3 TabBar with enhanced visual states by material
  • Native iOS CNTabBar with SF Symbols (cupertino_native package) *** not support cupertino = { forceUseMaterial: true } *** not support material = { forceUseCupertino: true }

Native iOS Tab Bar Integration: When useNativeCupertinoTabBar is enabled (default: true), BaseTabBar automatically uses CNTabBar from cupertino_native on iOS, providing authentic iOS 26 navigation with SF Symbols.

CNTabBar Customization Properties:

When using native CNTabBar, you can customize its appearance with:

  • cnTint: Tint color for selected items
  • cnHeight: Custom height for the tab bar
  • cnSplit: Enable split layout (left and right groups)
  • cnRightCount: Number of items on the right side when split
  • cnShrinkCentered: Shrink centered items in split layout
  • cnSplitSpacing: Spacing between split sections
  • cnBackgroundOpacity: Override background transparency (0.0 = fully transparent, 1.0 = fully opaque)

Note on Background Transparency: You can control CNTabBar transparency in two ways:

  1. Set backgroundColor with alpha: Colors.white.withOpacity(0.1)
  2. Use cnBackgroundOpacity to override: cnBackgroundOpacity: 0.1 (easier!)

The cnBackgroundOpacity property provides explicit control without affecting Material tab bars, making it ideal for iOS-specific customization.

SF Symbol Specification Methods:

Method 1: Convenience Factory (Recommended)

BaseTabBar(
  useNativeCupertinoTabBar: true,
  cnTint: Colors.blue, // Customize tint color
  cnBackgroundOpacity: 0.8, // Control transparency (0.0-1.0)
  cnSplit: true, // Enable split layout
  cnRightCount: 1, // 1 item on right side
  items: [
    BottomNavigationBarItemNativeExtension.withSFSymbol(
      sfSymbolName: SFSymbols.home,
      icon: Icon(Icons.home_outlined),
      activeIcon: Icon(Icons.home),
      label: 'Home',
    ),
  ],
)

Method 2: KeyedSubtree with Metadata

BottomNavigationBarItem(
  icon: KeyedSubtree(
    key: BaseNativeTabBarItemKey(SFSymbols.search),
    child: Icon(Icons.search_outlined),
  ),
  label: 'Search',
)

Search Functionality: Use the factory constructor for search-enabled tab bars:

BaseTabBar.search(
  items: [
    BottomNavigationBarItemNativeExtension.withSFSymbol(
      sfSymbolName: SFSymbols.home,
      icon: Icon(Icons.home_outlined),
      label: 'Home',
    ),
    BottomNavigationBarItemNativeExtension.withSFSymbol(
      sfSymbolName: SFSymbols.star,
      icon: Icon(Icons.star_outline),
      label: 'Favorites',
    ),
  ],
  searchConfig: CNSearchConfig(
    placeholder: 'Search tabs...',
    onSearchTextChanged: (text) => print('Search: $text'),
    resultsBuilder: (context, text) => SearchResultsWidget(text),
  ),
  cnTint: Colors.blue,
)

Method 3: Automatic Icon Mapping

BottomNavigationBarItem(
  icon: Icon(Icons.person_outline),
  label: 'Profile',
)

BaseTabBar will attempt to map common Material icons to corresponding SF Symbols.

SFSymbols Helper Class:

Use the SFSymbols class for common SF Symbol names:

  • SFSymbols.home → 'house.fill'
  • SFSymbols.search → 'magnifyingglass'
  • SFSymbols.profile → 'person.crop.circle'
  • SFSymbols.settings → 'gearshape.fill'
  • And 30+ more...

Forcing Rebuild/Refresh

Since BaseTabBar is a StatelessWidget, it rebuilds when its parent rebuilds. To force a rebuild when the tab bar's state changes, use one of these methods:

Method 1: Change the Key (Recommended)

class MyWidget extends StatefulWidget {
  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  int _refreshKey = 0;
  int _currentIndex = 0;
  
  void updateTabBar() {
    setState(() {
      _currentIndex = 2; // Change selected tab
      _refreshKey++; // Increment key to force rebuild
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return BaseTabBar(
      key: ValueKey(_refreshKey), // Or use BaseTabBar.refreshKey()
      currentIndex: _currentIndex,
      // ...
    );
  }
}

Method 2: Use UniqueKey for Each Rebuild

BaseTabBar(
  key: UniqueKey(), // Creates new key on every build
  // ...
)

Method 3: Use the Static Helper

BaseTabBar(
  key: BaseTabBar.refreshKey(), // Generates unique key
  // ...
)

Enhanced: 2024.01.20 with iOS 26 Liquid Glass Dynamic Material Enhanced: 2024.01.21 with Native iOS CNTabBar and SF Symbol integration Updated: 2024.10.30 - Added refresh documentation and helper methods

Inheritance

Constructors

BaseTabBar({Key? key, List<BottomNavigationBarItem>? items, ValueChanged<int>? onTap, int currentIndex = 0, double? iconSize, Color? backgroundColor, bool showIndicator = true, Color? activeColor, Color inactiveColor = CupertinoColors.inactiveGray, Border? border = const Border(top: BorderSide(color: _kDefaultTabBarBorderColor, width: 0.0, style: BorderStyle.solid)), double? elevation = 8.0, BottomNavigationBarType? type, Color? fixedColor, Color? selectedItemColor, Color? unselectedItemColor, IconThemeData? selectedIconTheme = const IconThemeData(), IconThemeData? unselectedIconTheme = const IconThemeData(), double selectedFontSize = 14.0, double unselectedFontSize = 12.0, TextStyle? selectedLabelStyle, TextStyle? unselectedLabelStyle, bool? showSelectedLabels = true, bool? showUnselectedLabels, MouseCursor? mouseCursor, bool? enableFeedback, bool enableLiquidGlass = true, double glassOpacity = 0.85, double reflectionIntensity = 0.6, bool adaptiveInteraction = true, bool hapticFeedback = true, bool useMaterial3Tabs = true, bool useNativeCupertinoTabBar = true, Color? cnTint, double? cnHeight, bool cnSplit = false, int cnRightCount = 1, bool cnShrinkCentered = true, double cnSplitSpacing = 8.0, double? cnBackgroundOpacity, CNSearchConfig? searchConfig, BaseParam? baseParam})
const
BaseTabBar.search({Key? key, List<BottomNavigationBarItem>? items, ValueChanged<int>? onTap, int currentIndex = 0, required CNSearchConfig searchConfig, double? iconSize, Color? backgroundColor, Color? activeColor, Color? cnTint, double? cnHeight, bool cnSplit = false, int cnRightCount = 1, bool cnShrinkCentered = true, double cnSplitSpacing = 8.0, double? cnBackgroundOpacity, bool useNativeCupertinoTabBar = true, BaseParam? baseParam})
Factory constructor for search-enabled tab bar
const

Properties

activeColor → Color?
*** general properties end *** *** cupertino properties start *** CupertinoTabBar.activeColor
final
adaptiveInteraction → bool
Enable adaptive interaction with real-time responsiveness Provides context-aware visual and haptic feedback for tab navigation
final
backgroundColor → Color?
CupertinoTabBar.backgroundColor or BottomNavigationBar.backgroundColor
final
baseParam → BaseParam?
Personalization parameters, gets platform parameters first, then mode parameters
finalinherited
border → Border?
CupertinoTabBar.border
final
cnBackgroundOpacity → double?
Background opacity for CNTabBar (0.0 to 1.0) When specified, applies this opacity to the backgroundColor for CNTabBar only. If not specified, uses the backgroundColor's alpha as-is. This provides explicit control over CNTabBar transparency without affecting Material tabs.
final
cnHeight → double?
CNTabBar.height - Custom height for the tab bar (iOS native) If not specified, uses the default CNTabBar height
final
cnRightCount → int
CNTabBar.rightCount - Number of items on the right side when split is enabled Only applies when cnSplit is true
final
cnShrinkCentered → bool
CNTabBar.shrinkCentered - Shrink centered items in split layout When true, centered items are shrunk to fit the available space
final
cnSplit → bool
CNTabBar.split - Enable split tab bar layout (iOS native) When true, creates a split layout with items distributed between left and right
final
cnSplitSpacing → double
CNTabBar.splitSpacing - Spacing between split sections Only applies when cnSplit is true
final
cnTint → Color?
*** iOS 26 Liquid Glass Dynamic Material properties end *** *** CNTabBar-specific properties start (cupertino_native package) *** CNTabBar.tint - Tint color for the tab bar (iOS native) Applied to selected items in the CNTabBar
final
currentIndex → int
CupertinoTabBar.currentIndex or BottomNavigationBar.currentIndex
final
elevation → double?
*** cupertino properties end *** *** material properties start *** BottomNavigationBar.elevation
final
enableFeedback → bool?
BottomNavigationBar.enableFeedback
final
enableLiquidGlass → bool
*** material properties end *** *** iOS 26 Liquid Glass Dynamic Material properties start *** Enable Liquid Glass Dynamic Material optical effects for tab bars Provides transparency, reflections, and adaptive visual states
final
fixedColor → Color?
BottomNavigationBar.fixedColor
final
glassOpacity → double
Glass transparency level for environmental awareness Creates optical clarity while maintaining navigation visibility (0.0 to 1.0)
final
hapticFeedback → bool
Enable haptic feedback for enhanced tab navigation experience Provides appropriate haptic responses for tab switches and interactions
final
hashCode → int
The hash code for this object.
no setterinherited
iconSize → double?
CupertinoTabBar.iconSize or BottomNavigationBar.iconSize
final
inactiveColor → Color
CupertinoTabBar.inactiveColor
final
items → List<BottomNavigationBarItem>?
*** general properties start *** See also:
final
key → Key?
Controls how one widget replaces another widget in the tree.
finalinherited
mouseCursor → MouseCursor?
BottomNavigationBar.mouseCursor
final
onTap → ValueChanged<int>?
CupertinoTabBar.onTap or BottomNavigationBar.onTap
final
reflectionIntensity → double
Reflection intensity for environmental responsiveness Simulates real-world glass reflection behavior (0.0 to 1.0)
final
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
searchConfig → CNSearchConfig?
Search configuration for search-enabled tab bar
final
selectedFontSize → double
BottomNavigationBar.selectedFontSize
final
selectedIconTheme → IconThemeData?
BottomNavigationBar.selectedIconTheme
final
selectedItemColor → Color?
BottomNavigationBar.selectedItemColor
final
selectedLabelStyle → TextStyle?
BottomNavigationBar.selectedLabelStyle
final
showIndicator → bool
when icon is null, then will add an indicator
final
showSelectedLabels → bool?
BottomNavigationBar.showSelectedLabels
final
showUnselectedLabels → bool?
BottomNavigationBar.showUnselectedLabels
final
type → BottomNavigationBarType?
BottomNavigationBar.type
final
unselectedFontSize → double
BottomNavigationBar.unselectedFontSize
final
unselectedIconTheme → IconThemeData?
BottomNavigationBar.unselectedIconTheme
final
unselectedItemColor → Color?
BottomNavigationBar.unselectedItemColor
final
unselectedLabelStyle → TextStyle?
BottomNavigationBar.unselectedLabelStyle
final
useMaterial3Tabs → bool
Use Material 3 TabBar instead of legacy BottomNavigationBar for Material tabs Provides modern Material Design 3 tab patterns and tokens
final
useNativeCupertinoTabBar → bool
Use native CNTabBar from cupertino_native package on iOS Provides authentic iOS 26 tab bar with SF Symbols and native styling When enabled, uses CNTabBar with CNTabBarItem and CNSymbol for icons
final

Methods

beforeBuild(BuildContext context) → void
Called before build
inherited
beforeBuildByCupertino(BuildContext context) → void
Called before buildByCupertino
inherited
beforeBuildByCupertinoNative(BuildContext context) → void
Called before buildByCupertinoNative (native iOS implementation)
inherited
beforeBuildByMaterial(BuildContext context) → void
Called before buildByMaterial
inherited
build(BuildContext context) → Widget
Describes the part of the user interface represented by this widget.
inherited
buildByCupertino(BuildContext context) → Widget
build on cupertino mode (Flutter implementation)
buildByCupertinoNative(BuildContext context) → Widget
build on cupertino mode with native iOS components (cupertino_native package) This is called when baseParam.nativeIOS = true Default implementation falls back to buildByCupertino()
buildByMaterial(BuildContext context) → Widget
build on material mode
buildCupertinoTabBar(BuildContext context) → CupertinoTabBar
Builds the raw CupertinoTabBar without Liquid Glass effects Used by BaseTabScaffold which needs the actual CupertinoTabBar instance
commonBuild(BuildContext context, BaseParam? baseParam) → dynamic
inherited
copyWith({ValueChanged<int>? onTap, required int currentIndex, BaseParam? baseParam}) → BaseTabBar
*** CNTabBar-specific properties end *** 用户BaseTabScaffold里构建bottomNavigationBar
createElement() → StatelessElement
Creates a StatelessElement to manage this widget's location in the tree.
inherited
debugDescribeChildren() → List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
inherited
getBuildMode(BaseParam? baseParam) → WidgetBuildMode
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep.
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) → String
A string representation of this object.
inherited
toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) → String
Returns a string representation of this node and its descendants.
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String
Returns a one-line detailed description of the object.
inherited
toStringShort() → String
A short, textual description of this widget.
inherited
valueOf(String key, dynamic value) → dynamic
inherited
valueOfBaseParam(BaseParam? baseParam, String key, dynamic value) → dynamic
No reflection available in Dart First get value from platform, then from mode, finally from value itself
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited

Static Methods

refreshKey() → Key
Creates a unique key for forcing widget rebuild