BaseNavigationBar class

Internal: CNNavigationBarAction from cupertino_native package Used only for iOS platform channel communication Public API should use BaseNavigationBarAction instead BaseNavigationBar - Cross-platform navigation bar with native iOS support

Uses CNNavigationBar (Cupertino Native) for iOS - provides native iOS navigation bar with large title mode, transparency, and flexible actions via UINavigationBar. Uses Material AppBar for Android.

*** use cupertino = { forceUseMaterial: true } force use Material AppBar on iOS *** use material = { forceUseCupertino: true } force use CNNavigationBar on Android

Features:

  • Native iOS UINavigationBar via CNNavigationBar (cupertino_native package)
  • Material Design AppBar for Android
  • Leading, title, and trailing actions
  • Large title mode support
  • Transparency with blur effects
  • Search functionality via factory constructor
  • Segmented control integration (iOS native)
  • Built-in liquid glass effects on iOS (no manual wrapper needed)
  • Automatic platform-specific conversion of actions

Example:

BaseNavigationBar(
  leading: [
    BaseNavigationBarAction(
      icon: CNSymbol('chevron.left'),
      onPressed: () => Navigator.pop(context),
    ),
    BaseNavigationBarAction(
      label: 'Back',
      onPressed: () => Navigator.pop(context),
    ),
  ],
  title: 'Navigation Bar',
  trailing: [
    BaseNavigationBarAction(
      icon: CNSymbol('gear'),
      onPressed: () => print('Settings'),
    ),
    BaseNavigationBarAction(
      icon: CNSymbol('plus'),
      onPressed: () => print('Add'),
    ),
  ],
  tint: CupertinoColors.label,
  transparent: false,
  largeTitle: false,
)

For segmented control, add the following parameters:

BaseNavigationBar(
  title: 'Native Nav Bar',
  titleSize: 20,
  onTitlePressed: () => print('Title tapped!'),
  segmentedControlLabels: ['Notifications', 'Buddy Requests'],
  segmentedControlSelectedIndex: _selectedIndex,
  onSegmentedControlValueChanged: (index) {
    setState(() => _selectedIndex = index);
  },
  segmentedControlHeight: 40,
  segmentedControlTint: CupertinoColors.white,
  trailing: [
    BaseNavigationBarAction(
      icon: CNSymbol('gear'),
      onPressed: () => print('Settings'),
    ),
  ],
)

For search functionality, use the factory constructor:

BaseNavigationBar.search(
  leading: [
    BaseNavigationBarAction(icon: CNSymbol('chevron.left'), onPressed: () {}),
  ],
  trailing: [
    BaseNavigationBarAction(icon: CNSymbol('ellipsis.circle'), onPressed: () {}),
  ],
  searchConfig: CNSearchConfig(
    placeholder: 'Search',
    onSearchTextChanged: (text) => print(text),
    resultsBuilder: (context, text) => SearchResults(text),
  ),
)

Available action types:

  • BaseNavigationBarAction() - Regular action with icon/label
  • BaseNavigationBarAction.fixedSpace(5) - Fixed spacing
  • BaseNavigationBarAction.flexibleSpace() - Flexible spacing

Forcing Rebuild/Refresh

Since BaseNavigationBar is a StatelessWidget, it rebuilds when its parent rebuilds. To force a rebuild when the navigation 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;
  List<BaseNavigationBarAction> _actions = [...];

  void updateActions() {
    setState(() {
      _actions = [...]; // Update actions
      _refreshKey++; // Increment key to force rebuild
    });
  }

  @override
  Widget build(BuildContext context) {
    return BaseNavigationBar(
      key: ValueKey(_refreshKey), // Or use BaseNavigationBar.refreshKey()
      trailing: _actions,
      // ...
    );
  }
}

Method 2: Use UniqueKey for Each Rebuild

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

Method 3: Use the Static Helper

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

Updated: 2024.10.25 - Refactored to use BaseNavigationBarAction in public API Updated: 2024.10.30 - Added refresh documentation and helper methods

Inheritance

Constructors

BaseNavigationBar({Key? key, List<BaseNavigationBarAction>? leading, String? title, List<BaseNavigationBarAction>? trailing, Color? tint, bool transparent = false, bool largeTitle = false, double? height, double? titleSize, VoidCallback? onTitlePressed, CNSearchConfig? searchConfig, List<String>? segmentedControlLabels, int? segmentedControlSelectedIndex, ValueChanged<int>? onSegmentedControlValueChanged, double? segmentedControlHeight, Color? segmentedControlTint, double? segmentedControlLabelSize, BaseParam? baseParam})
const
BaseNavigationBar.search({Key? key, List<BaseNavigationBarAction>? leading, List<BaseNavigationBarAction>? trailing, required CNSearchConfig searchConfig, Color? tint, bool transparent = false, bool largeTitle = false, double? height, double? titleSize, VoidCallback? onTitlePressed, BaseParam? baseParam})
Factory constructor for search-enabled navigation bar
const

Properties

baseParam → BaseParam?
Personalization parameters, gets platform parameters first, then mode parameters
finalinherited
hashCode → int
The hash code for this object.
no setterinherited
height → double?
Custom height for the navigation bar
final
key → Key?
Controls how one widget replaces another widget in the tree.
finalinherited
largeTitle → bool
Whether to use large title style
final
leading → List<BaseNavigationBarAction>?
Leading navigation actions
final
onSegmentedControlValueChanged → ValueChanged<int>?
Callback when segmented control value changes (iOS native)
final
onTitlePressed → VoidCallback?
Callback when title is tapped
final
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
searchConfig → CNSearchConfig?
Search configuration for search-enabled navigation bar
final
segmentedControlHeight → double?
Custom height for segmented control (iOS native)
final
segmentedControlLabels → List<String>?
Labels for segmented control (iOS native) When provided, displays a segmented control below the navigation bar
final
segmentedControlLabelSize → double?
Label size for segmented control text (iOS native)
final
segmentedControlSelectedIndex → int?
Selected index for segmented control (iOS native)
final
segmentedControlTint → Color?
Tint color for segmented control (iOS native)
final
tint → Color?
Tint color for icons and text
final
title → String?
Navigation bar title
final
titleSize → double?
Title text size
final
trailing → List<BaseNavigationBarAction>?
Trailing navigation actions
final
transparent → bool
Whether the navigation bar should be transparent
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) → dynamic
build on cupertino mode with native iOS components (cupertino_native package) This is called when baseParam.nativeIOS = true Default implementation falls back to buildByCupertino()
inherited
buildByMaterial(BuildContext context) → Widget
build on material mode
commonBuild(BuildContext context, BaseParam? baseParam) → dynamic
inherited
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