### Basic PersistentTabView Implementation Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt This example demonstrates a basic setup of PersistentTabView, replacing the main Scaffold. It includes configuration for background color, state management, history preservation, Android back button handling, scroll behavior, and screen transitions. Each tab is defined with a screen and item configuration. ```dart import 'package:flutter/material.dart'; import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: PersistentTabView( // Background color visible behind transparent/rounded nav bars backgroundColor: Colors.grey[100]!, // Preserve each tab's widget tree when switching tabs stateManagement: true, // Also keep the pushed-screen history per tab keepNavigatorHistory: true, // Handle the Android back button automatically handleAndroidBackButtonPress: true, // Hide the nav bar when scrolling down (px threshold) hideOnScrollVelocity: 200, // Animated transition when switching tabs screenTransitionAnimation: const ScreenTransitionAnimation( duration: Duration(milliseconds: 250), curve: Curves.easeInOut, ), onTabChanged: (index) => debugPrint('Switched to tab $index'), tabs: [ PersistentTabConfig( screen: const HomeScreen(), item: ItemConfig( icon: const Icon(Icons.home), title: 'Home', activeForegroundColor: Colors.blue, inactiveForegroundColor: Colors.grey, ), ), PersistentTabConfig( screen: const MessagesScreen(), item: ItemConfig( icon: const Icon(Icons.message), title: 'Messages', activeForegroundColor: Colors.blue, ), ), PersistentTabConfig( screen: const SettingsScreen(), item: ItemConfig( icon: const Icon(Icons.settings), title: 'Settings', activeForegroundColor: Colors.blue, ), ), ], navBarBuilder: (navBarConfig) => Style1BottomNavBar( navBarConfig: navBarConfig, ), ), ); } } ``` -------------------------------- ### Installation Configuration Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/linux/CMakeLists.txt Configures the installation process, setting the install prefix to a bundle directory and ensuring a clean build bundle on each run. Installs the application executable, ICU data, Flutter library, bundled libraries, and native assets. ```cmake set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() install(CODE " file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") " COMPONENT Runtime) set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) install(FILES "${bundled_library}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endforeach(bundled_library) set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") install(DIRECTORY "${NATIVE_ASSETS_DIR}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) ``` -------------------------------- ### Install Flutter Assets Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/linux/CMakeLists.txt Installs the Flutter assets directory to the application's data directory. It first removes any existing assets to ensure a clean installation. ```cmake set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install( CODE " file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") " COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) ``` -------------------------------- ### Install AOT Library Conditionally Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/linux/CMakeLists.txt Installs the Ahead-Of-Time (AOT) compiled library to the application's library directory, but only for non-debug build types. ```cmake if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() ``` -------------------------------- ### ItemConfig for Navigation Bar Items Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt Configure individual navigation bar items with icons, titles, and colors. This example shows active and inactive icons, text styles, and background colors for selected items. ```dart ItemConfig( // Active (selected) icon widget icon: const Icon(Icons.home), // Optional separate icon shown when not selected inactiveIcon: const Icon(Icons.home_outlined), title: 'Home', iconSize: 26.0, activeForegroundColor: Colors.deepPurple, inactiveForegroundColor: Colors.grey, // Background color of the item when selected (used by some styles) // Defaults to activeForegroundColor.withOpacity(0.2) activeColorSecondary: Colors.deepPurple.withOpacity(0.15), inactiveBackgroundColor: Colors.transparent, textStyle: const TextStyle( fontSize: 12, fontWeight: FontWeight.w500, ), ) ``` -------------------------------- ### Install Persistent Bottom Nav Bar V2 Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/README.md Add the persistent_bottom_nav_bar_v2 package to your Flutter project dependencies. ```bash dart pub add persistent_bottom_nav_bar_v2 ``` -------------------------------- ### Add notification counters to navigation bar icons Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/README.md Utilize the `badges` package to display notification counters or unread indicators on navigation bar icons. This example shows how to wrap an `Icon` with a `Badge` widget. ```dart PersistentTabConfig( screen: ..., item: ItemConfig( icon: Badge( animationType: BadgeAnimationType.scale, badgeContent: UnreadIndicator(), child: const Icon( Icons.chat_rounded, ), ), title: "Chat", ), ), ``` -------------------------------- ### Configure Standard and Action Tabs Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt Define standard tabs that display a screen or action tabs that trigger custom events like showing a modal. Use `PersistentTabConfig.noScreen` for action tabs. ```dart PersistentTabConfig( screen: const ProfileScreen(), item: ItemConfig( icon: const Icon(Icons.person), title: 'Profile', ), // Pass a ScrollController to enable scroll-to-top on double-tap scrollController: _profileScrollController, navigatorConfig: NavigatorConfig( // Named routes available inside this tab's navigator routes: { '/profile/edit': (context) => const EditProfileScreen(), }, navigatorObservers: [MyAnalyticsObserver()], ), ) // Action tab: no screen — opens a bottom sheet instead PersistentTabConfig.noScreen( item: ItemConfig( icon: const Icon(Icons.add_circle_outline), title: 'New', activeForegroundColor: Colors.green, ), onPressed: (context) { showModalBottomSheet( context: context, useRootNavigator: true, // renders above the nav bar builder: (_) => const CreatePostSheet(), ); }, ) ``` -------------------------------- ### Apply Standard Build Settings Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/windows/runner/CMakeLists.txt Applies a predefined set of build settings to the executable target. This can be customized or removed if the application requires specific, non-standard build configurations. ```cmake apply_standard_settings(${BINARY_NAME}) ``` -------------------------------- ### Find and check system dependencies Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/linux/flutter/CMakeLists.txt This section uses PkgConfig to find and check for required system libraries like GTK, GLIB, and GIO. These are essential for Flutter's Linux desktop integration. ```cmake find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) ``` -------------------------------- ### Project Configuration Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/linux/CMakeLists.txt Sets the minimum CMake version and project name. Defines the executable name and application ID. Use 'set(BINARY_NAME "...")' to change the on-disk name of your application. ```cmake cmake_minimum_required(VERSION 3.10) project(runner LANGUAGES CXX) set(BINARY_NAME "example") set(APPLICATION_ID "com.example.example") cmake_policy(SET CMP0063 NEW) set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") ``` -------------------------------- ### Utilize Prebuilt Nav Bar Styles Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt Choose from seventeen prebuilt navigation bar styles (Style1-Style16 and Neumorphic). Most accept `navBarConfig` and `navBarDecoration`; animated styles also take `itemAnimationProperties`. ```dart // Style 1 — simple icon + label Style1BottomNavBar(navBarConfig: navBarConfig) // Style 6 — animated, floating pill indicator Style6BottomNavBar( navBarConfig: navBarConfig, navBarDecoration: const NavBarDecoration(color: Colors.black87), itemAnimationProperties: const ItemAnimation( duration: Duration(milliseconds: 400), curve: Curves.fastOutSlowIn, ), ) // Neumorphic style NeumorphicBottomNavBar( navBarConfig: navBarConfig, navBarDecoration: NavBarDecoration( color: const Color(0xFFE0E5EC), borderRadius: BorderRadius.circular(12), ), neumorphicProperties: const NeumorphicProperties( bevel: 12, depth: 4, ), ) ``` -------------------------------- ### Application Executable Definition Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/linux/CMakeLists.txt Defines the main executable for the application, including source files and generated plugin registration. Applies standard build settings using the 'apply_standard_settings' function. ```cmake add_executable(${BINARY_NAME} "main.cc" "my_application.cc" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" ) apply_standard_settings(${BINARY_NAME}) ``` -------------------------------- ### Link Libraries and Include Directories Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/windows/runner/CMakeLists.txt Adds necessary dependency libraries and include directories for the application. Application-specific dependencies should also be added here. ```cmake target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) ``` ```cmake target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") ``` ```cmake target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") ``` -------------------------------- ### Flutter and System Dependencies Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/linux/CMakeLists.txt Includes the Flutter managed directory and checks for GTK+ 3.0 using PkgConfig. Defines the application ID as a preprocessor macro. ```cmake set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") add_subdirectory(${FLUTTER_MANAGED_DIR}) find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") ``` -------------------------------- ### Create AppBar with Drawer Button Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/MigrationGuide.md Use this snippet to create an AppBar that includes a button to open the drawer. Ensure the `Scaffold.of(context).openDrawer()` call is correctly placed within the `onPressed` handler. ```dart AppBar( leading: Builder( builder: (BuildContext context) { return IconButton( icon: const Icon(Icons.menu), onPressed: () { Scaffold.of(context).openDrawer(); }, tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip, ); }, ), ) ``` -------------------------------- ### Generated Plugin Rules Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/linux/CMakeLists.txt Includes the CMake script that manages building plugins and adding them to the application. ```cmake include(flutter/generated_plugins.cmake) ``` -------------------------------- ### Configure Flutter library and headers Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/linux/flutter/CMakeLists.txt Defines the path to the Flutter Linux library and its header files. It also sets up interface include directories and links against system libraries and the Flutter library. ```cmake set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) list(APPEND FLUTTER_LIBRARY_HEADERS "fl_basic_message_channel.h" "fl_binary_codec.h" "fl_binary_messenger.h" "fl_dart_project.h" "fl_engine.h" "fl_json_message_codec.h" "fl_json_method_codec.h" "fl_message_codec.h" "fl_method_call.h" "fl_method_channel.h" "fl_method_codec.h" "fl_method_response.h" "fl_plugin_registrar.h" "fl_plugin_registry.h" "fl_standard_message_codec.h" "fl_standard_method_codec.h" "fl_string_codec.h" "fl_value.h" "fl_view.h" "flutter_linux.h" ) list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") add_library(flutter INTERFACE) target_include_directories(flutter INTERFACE "${EPHEMERAL_DIR}" ) target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") target_link_libraries(flutter INTERFACE PkgConfig::GTK PkgConfig::GLIB PkgConfig::GIO ) add_dependencies(flutter flutter_assemble) ``` -------------------------------- ### Linking Libraries Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/linux/CMakeLists.txt Links the application executable against the Flutter library and GTK+. Add any other application-specific dependencies here. ```cmake target_link_libraries(${BINARY_NAME} PRIVATE flutter) target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) ``` -------------------------------- ### Default Page Transition Animation Builder Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/README.md This is the default implementation for animating page transitions when switching tabs. It uses FractionalTranslation to slide pages. ```dart final double yOffset = newIndex > index ? -animationValue : (newIndex < index ? animationValue : (index < oldIndex ? animationValue - 1 : 1 - animationValue)); return FractionalTranslation( translation: Offset(yOffset, 0), child: child, ); ``` -------------------------------- ### Configure Selected Tab Press Behavior Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt Define actions when a user taps the currently active tab. Options include executing a callback, popping screens from the stack, or scrolling content to the top. ```dart PersistentTabView( tabs: [ /* ... */ ], navBarBuilder: (config) => Style1BottomNavBar(navBarConfig: config), selectedTabPressConfig: SelectedTabPressConfig( // Called with `true` if there were pushed screens, `false` if at root onPressed: (hadScreensOnStack) { debugPrint('Re-tapped active tab; had stack: $hadScreensOnStack'); }, // PopActionType.all → pop entire stack to root (default) // PopActionType.single → pop one screen at a time // PopActionType.none → do nothing popAction: PopActionType.all, // Scroll the tab's content back to the top (requires scrollController) scrollToTop: true, ), ) ``` -------------------------------- ### Programmatic Navigation Functions Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt Utilize utility functions for pushing screens with or without the navigation bar visible, and for managing the navigation stack. ```dart // Push a screen and keep the nav bar visible pushScreen( context, screen: const DetailScreen(), withNavBar: true, pageTransitionAnimation: PageTransitionAnimation.slideUp, ); // Push a screen and hide the nav bar (full-screen) pushScreenWithoutNavBar(context, const FullScreenVideoPlayer()); // Push using a custom route and keep the nav bar pushWithNavBar( context, MaterialPageRoute(builder: (_) => const EditScreen()), ); // Push using a custom route and hide the nav bar pushWithoutNavBar( context, CupertinoPageRoute(builder: (_) => const OnboardingScreen()), ); // Pop all pushed screens in the current tab back to its root popAllScreensOfCurrentTab(context); // Pop to a specific named screen in the current tab's stack Navigator.of(context).popUntil( (route) => route.settings.name == '/profile', ); ``` -------------------------------- ### Runtime Output Directory Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/linux/CMakeLists.txt Sets the runtime output directory for the executable to a subdirectory to prevent users from running the unbundled copy. This ensures resources are correctly located. ```cmake set_target_properties(${BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" ) ``` -------------------------------- ### Migrate Tabs and Screens Configuration Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/MigrationGuide.md The separate `screens` and `items` lists are merged into a single `tabs` list. `PersistentBottomNavBarItem` is renamed to `ItemConfig`, and each tab is now represented by `PersistentTabConfig`. ```dart PersistentTabView( ..., screens: [ Screen1(), Screen2(), Screen3(), ], items: [ PersistentBottomNavBarItem( icon: Icon(Icons.home), title: "Home" ), PersistentBottomNavBarItem( icon: Icon(Icons.home), title: "Home" ), PersistentBottomNavBarItem( icon: Icon(Icons.home), title: "Home" ), ] ), ``` ```dart PersistentTabView( ..., tabs: [ PersistentTabConfig( screen: Screen1(), item: ItemConfig( icon: Icon(Icons.home), title: "Home", ), ), PersistentTabConfig( screen: Screen2(), item: ItemConfig( icon: Icon(Icons.home), title: "Home", ), ), PersistentTabConfig( screen: Screen3(), item: ItemConfig( icon: Icon(Icons.home), title: "Home", ), ), ], ), ``` -------------------------------- ### Build a Custom Navigation Bar with MinimalNavBar Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt Implement a custom navigation bar by providing a widget to `navBarBuilder`. Use `navBarConfig.onItemSelected(index)` to handle item selection. ```dart class MinimalNavBar extends StatelessWidget { const MinimalNavBar({ required this.navBarConfig, this.navBarDecoration = const NavBarDecoration(), super.key, }); final NavBarConfig navBarConfig; final NavBarDecoration navBarDecoration; @override Widget build(BuildContext context) { return DecoratedNavBar( decoration: navBarDecoration, height: kBottomNavigationBarHeight, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ for (final (index, item) in navBarConfig.items.indexed) Expanded( child: InkWell( onTap: () => navBarConfig.onItemSelected(index), // required child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ IconTheme( data: IconThemeData( color: navBarConfig.selectedIndex == index ? item.activeForegroundColor : item.inactiveForegroundColor, size: item.iconSize, ), child: navBarConfig.selectedIndex == index ? item.icon : item.inactiveIcon, ), if (item.title != null) Text( item.title!, style: item.textStyle.apply( color: navBarConfig.selectedIndex == index ? item.activeForegroundColor : item.inactiveForegroundColor, ), ), ], ), ), ), ], ), ); } } // Usage PersistentTabView( tabs: [ /* ... */ ], navBarBuilder: (config) => MinimalNavBar(navBarConfig: config), ) ``` -------------------------------- ### Build Configuration Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/linux/CMakeLists.txt Sets the default build type to 'Debug' if not already defined. Ensures that only valid build types ('Debug', 'Profile', 'Release') are accepted. ```cmake if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Flutter build mode" FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Profile" "Release") endif() ``` -------------------------------- ### Create a Custom Navigation Bar Widget Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/README.md Implement a custom navigation bar by extending StatelessWidget and using NavBarConfig. Ensure `onItemSelected` is called when an item is tapped to trigger tab changes. ```dart class CustomNavBar extends StatelessWidget { final NavBarConfig navBarConfig; // You are free to omit this, but in combination with `DecoratedNavBar` it might make your start easier final NavBarDecoration navBarDecoration; const CustomNavBar({ super.key, required this.navBarConfig, this.navBarDecoration = const NavBarDecoration(), }); Widget _buildItem(ItemConfig item, bool isSelected) { final title = item.title; return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: IconTheme( data: IconThemeData( size: item.iconSize, color: isSelected ? item.activeForegroundColor : item.inactiveForegroundColor, ), child: isSelected ? item.icon : item.inactiveIcon, ), ), if (title != null) Padding( padding: const EdgeInsets.only(top: 15.0), child: Material( type: MaterialType.transparency, child: FittedBox( child: Text( title, style: item.textStyle.apply( color: isSelected ? item.activeForegroundColor : item.inactiveForegroundColor, ), ), ), ), ), ], ); } @override Widget build(BuildContext context) { return DecoratedNavBar( decoration: navBarDecoration, height: kBottomNavigationBarHeight, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.center, children: [ for (final (index, item) in navBarConfig.items.indexed) Expanded( child: InkWell( // This is the most important part. Without this, nothing would happen if you tap on an item. onTap: () => navBarConfig.onItemSelected(index), child: _buildItem(item, navBarConfig.selectedIndex == index), ), ), ], ), ); } } ``` -------------------------------- ### Integrate Persistent Bottom Navigation Bar with GoRouter Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/README.md Use `PersistentTabView.router` and `PersistentRouterTabConfig` when integrating with go_router. Ensure the `navigationShell` is passed to `PersistentTabView.router` and screens are defined by routes within `StatefulShellBranch`. ```dart StatefulShellRoute.indexedStack( builder: (context, state, navigationShell) => PersistentTabView.router( tabs: [ PersistentRouterTabConfig( item: ItemConfig( icon: const Icon(Icons.home), title: "Home", ), ), PersistentRouterTabConfig( item: ItemConfig( icon: const Icon(Icons.message), title: "Messages", ), ), PersistentRouterTabConfig( item: ItemConfig( icon: const Icon(Icons.settings), title: "Settings", ), ), ], navBarBuilder: (navBarConfig) => Style1BottomNavBar( navBarConfig: navBarConfig, ), navigationShell: navigationShell, ), branches: [ // The route branch for the 1st Tab StatefulShellBranch( routes: [ GoRoute( path: "/home", builder: (context, state) => const MainScreen( useRouter: true, ), routes: [ GoRoute( path: "detail", builder: (context, state) => const MainScreen2( useRouter: true, ), ), ], ), ], ), // The route branch for 2nd Tab StatefulShellBranch( routes: [ GoRoute( path: "/messages", builder: (context, state) => const MainScreen( useRouter: true, ), ), ], ), // The route branch for 3rd Tab StatefulShellBranch( routes: [ GoRoute( path: "/settings", builder: (context, state) => const MainScreen( useRouter: true, ), ), ], ), ], ) ``` -------------------------------- ### Define Executable Target Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/windows/runner/CMakeLists.txt Defines the main executable for the Windows application. Source files and resources are listed here. Ensure BINARY_NAME is consistent with the top-level CMakeLists.txt for `flutter run` to function correctly. ```cmake add_executable(${BINARY_NAME} WIN32 "flutter_window.cpp" "main.cpp" "utils.cpp" "win32_window.cpp" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" "Runner.rc" "runner.exe.manifest" ) ``` -------------------------------- ### Pop to a specific screen in the navigation stack Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/README.md Use `Navigator.of(context).popUntil` to navigate back to a screen identified by its settings name within the current tab's navigation stack. ```dart Navigator.of(context).popUntil((route) { return route.settings.name == "ScreenToPopBackTo"; }); ``` -------------------------------- ### Configure Per-Tab Navigator Settings Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt Set specific navigator configurations for each tab, including initial routes, named routes, observers, and custom navigator keys. ```dart PersistentTabConfig( screen: const ShopScreen(), item: ItemConfig(icon: const Icon(Icons.store), title: 'Shop'), navigatorConfig: NavigatorConfig( initialRoute: '/shop', routes: { '/shop/product': (context) => const ProductDetailScreen(), '/shop/cart': (context) => const CartScreen(), '/shop/checkout': (context) => const CheckoutScreen(), }, navigatorObservers: [FirebaseAnalyticsObserver(analytics: analytics)], navigatorKey: GlobalKey(), ), ) ``` -------------------------------- ### Implement Custom Animated Tab Builder Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt Replace the default slide animation with a custom builder. This allows for simultaneous access to outgoing and incoming tab animations for complex transitions like fades. ```dart PersistentTabView( tabs: [ /* ... */ ], navBarBuilder: (config) => Style1BottomNavBar(navBarConfig: config), animatedTabBuilder: (context, index, animationValue, oldIndex, newIndex, child) { // Fade transition instead of the default slide final opacity = (index == newIndex) ? animationValue // new tab fades in : 1.0 - animationValue; // old tab fades out return Opacity(opacity: opacity.clamp(0.0, 1.0), child: child); }, ) ``` -------------------------------- ### Configure Screen Transition Animation Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt Control the sliding animation between tabs. Set a custom duration and curve, or disable it entirely using ScreenTransitionAnimation.none(). ```dart PersistentTabView( tabs: [ /* ... */ ], navBarBuilder: (config) => Style1BottomNavBar(navBarConfig: config), // Default: 200 ms, Curves.ease screenTransitionAnimation: const ScreenTransitionAnimation( duration: Duration(milliseconds: 300), curve: Curves.easeInOut, ), // Or disable it entirely: // screenTransitionAnimation: ScreenTransitionAnimation.none(), ) ``` -------------------------------- ### PersistentTabView with Drawer Integration Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt Implement a persistent drawer accessible from all tabs using PersistentTabView. The drawer can be opened via the PersistentTabController. Ensure the leading icon in the AppBar is configured to call `_controller.openDrawer`. ```dart final _controller = PersistentTabController(); PersistentTabView( controller: _controller, drawer: Drawer( child: ListView( children: [ const DrawerHeader(child: Text('My App')), ListTile( title: const Text('Profile'), onTap: () => _controller.jumpToTab(2), ), ], ), ), tabs: [ PersistentTabConfig( screen: Scaffold( appBar: AppBar( leading: IconButton( icon: const Icon(Icons.menu), onPressed: _controller.openDrawer, ), title: const Text('Home'), ), body: const HomeBody(), ), item: ItemConfig(icon: const Icon(Icons.home), title: 'Home'), ), /* ... more tabs */ ], navBarBuilder: (config) => Style1BottomNavBar(navBarConfig: config), ) ``` -------------------------------- ### Import Persistent Bottom Nav Bar V2 Package Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/README.md Import the necessary package into your Dart file to use its components. ```dart import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart'; ``` -------------------------------- ### Push Screen with Navigation Bar (Specific Function) Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/README.md A dedicated utility function for pushing a new screen onto the navigation stack, ensuring the bottom navigation bar remains visible. ```dart pushScreenWithNavBar( context, screen: MainScreen(), ); ``` -------------------------------- ### Programmatically Switch Tabs with PersistentTabController Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/README.md Utilize a PersistentTabController to manage and switch tabs programmatically within the PersistentTabView. Initialize the controller with an initial index. ```dart PersistentTabController _controller = PersistentTabController(initialIndex: 0); PersistentTabView( controller: _controller, ... ); _controller.jumpToTab(2); // Navigate to the previously selected Tab _controller.jumpToPreviousTab(); ``` -------------------------------- ### Apply Page Transition Animations Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt Control the transition animation used by `pushScreen` by selecting from the `PageTransitionAnimation` enum values. ```dart pushScreen( context, screen: const PhotoViewer(), withNavBar: false, pageTransitionAnimation: PageTransitionAnimation.fade, ); ``` -------------------------------- ### Standard Compilation Settings Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/linux/CMakeLists.txt Defines a function to apply common compilation settings to targets, including C++ standard, warning levels, optimization, and NDEBUG definition. Avoid adding new options here unless necessary, as plugins use this function by default. ```cmake function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_14) target_compile_options(${TARGET} PRIVATE -Wall -Werror) target_compile_options(${TARGET} PRIVATE "<$>:-O3>") target_compile_definitions(${TARGET} PRIVATE "<$>:NDEBUG>") endfunction() ``` -------------------------------- ### Cross-Building Configuration Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/linux/CMakeLists.txt Configures CMake for cross-building by setting the sysroot and find root path modes. This is used when building for a different architecture or operating system. ```cmake if(FLUTTER_TARGET_PLATFORM_SYSROOT) set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) endif() ``` -------------------------------- ### Define list_prepend function for CMake < 3.10 Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/linux/flutter/CMakeLists.txt This function prepends a prefix to each element in a list. It is used because the list(TRANSFORM ... PREPEND ...) command is not available in CMake version 3.10. ```cmake function(list_prepend LIST_NAME PREFIX) set(NEW_LIST "") foreach(element ${${LIST_NAME}}) list(APPEND NEW_LIST "${PREFIX}${element}") endforeach(element) set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) endfunction() ``` -------------------------------- ### Custom command for Flutter tool backend Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/linux/flutter/CMakeLists.txt This custom command invokes the Flutter tool backend script to generate necessary build artifacts like the Flutter library and headers. A phony target is used to ensure it runs on every build. ```cmake add_custom_command( OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/_phony_ COMMAND ${CMAKE_COMMAND} -E env ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} VERBATIM ) add_custom_target(flutter_assemble DEPENDS "${FLUTTER_LIBRARY}" ${FLUTTER_LIBRARY_HEADERS} ) ``` -------------------------------- ### Add Version Preprocessor Definitions Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/windows/runner/CMakeLists.txt Adds preprocessor definitions to the build configuration, embedding Flutter version information directly into the compiled code. This allows the application to access version details at runtime. ```cmake target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") ``` ```cmake target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") ``` ```cmake target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") ``` ```cmake target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") ``` ```cmake target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") ``` -------------------------------- ### Push Screen with Navigation Bar Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/README.md Utility function to push a new screen onto the navigation stack while keeping the bottom navigation bar visible. ```dart pushScreen( context, screen: MainScreen(), withNavBar: true, // or false ); ``` -------------------------------- ### go_router Integration with PersistentTabView.router Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt Integrate PersistentTabView.router within a StatefulShellRoute.indexedStack for deep-linkable navigation. Ensure your MaterialApp uses the router configuration. ```dart import 'package:go_router/go_router.dart'; import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart'; final _rootNavigatorKey = GlobalKey(); final _shellNavigatorKey = GlobalKey(); final router = GoRouter( navigatorKey: _rootNavigatorKey, initialLocation: '/home', routes: [ StatefulShellRoute.indexedStack( builder: (context, state, navigationShell) => PersistentTabView.router( navigationShell: navigationShell, tabs: [ PersistentRouterTabConfig( item: ItemConfig(icon: const Icon(Icons.home), title: 'Home'), ), PersistentRouterTabConfig( item: ItemConfig(icon: const Icon(Icons.message), title: 'Messages'), ), PersistentRouterTabConfig( item: ItemConfig(icon: const Icon(Icons.settings), title: 'Settings'), ), ], navBarBuilder: (config) => Style1BottomNavBar(navBarConfig: config), ), branches: [ StatefulShellBranch( navigatorKey: _shellNavigatorKey, routes: [ GoRoute( path: '/home', builder: (_, __) => const HomeScreen(), routes: [ // parentNavigatorKey: _rootNavigatorKey pushes ABOVE the nav bar GoRoute( parentNavigatorKey: _rootNavigatorKey, path: 'detail', builder: (_, __) => const DetailScreen(), ), ], ), ], ), StatefulShellBranch( routes: [ GoRoute( path: '/messages', builder: (_, __) => const MessagesScreen(), routes: [ GoRoute( path: 'thread/:id', builder: (context, state) => ThreadScreen(id: state.pathParameters['id']!), ), ], ), ], ), StatefulShellBranch( routes: [ GoRoute( path: '/settings', builder: (_, __) => const SettingsScreen(), ), ], ), ], ), ], ); // In main: MaterialApp.router(routerConfig: router) ``` -------------------------------- ### Customize NavBar with Decoration and Animation Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/README.md Use NavBarDecoration to set background color, border radius, and shadow. ItemAnimationProperties can adjust the duration and curve of item transitions. ```dart PersistentTabView( tabs: ..., navBarBuilder: (navBarConfig) => Style2BottomNavBar( navBarConfig: navBarConfig, navBarDecoration: NavBarDecoration( color: Colors.blue, borderRadius: BorderRadius.circular(8), boxShadow: [ BoxShadow( color: Colors.black26, blurRadius: 10, ), ], ), itemAnimationProperties: ItemAnimation( duration: const Duration(milliseconds: 400), curve: Curves.easeInOut, ) ), ), ``` -------------------------------- ### Migrate onPressed from PersistentBottomNavBarItem to PersistentTabConfig Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/MigrationGuide.md The `onPressed` callback has moved from `PersistentBottomNavBarItem` to `PersistentTabConfig`. Use `PersistentTabConfig.noScreen` to define a tab item without a screen, specifying the `onPressed` callback. ```dart PersistentBottomNavBarItem( ..., onPressed: (ctx) => showDialog(...), ), ``` ```dart PersistentTabConfig.noScreen( item: ItemConfig( ..., ), onPressed: (ctx) => showDialog(...), ), ``` -------------------------------- ### Integrate Animated Icons with AnimatedIconWrapper Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt Wrap Flutter's `AnimatedIcon` with `AnimatedIconWrapper` to automatically drive animations on tab enter/exit. The controller is handled internally. ```dart PersistentTabView( tabs: [ PersistentTabConfig( screen: const HomeScreen(), item: ItemConfig( // AnimatedIconWrapper handles the AnimationController internally icon: AnimatedIconWrapper( icon: AnimatedIcons.home_menu, duration: const Duration(milliseconds: 350), curve: Curves.easeInOut, ), title: 'Home', activeForegroundColor: Colors.indigo, ), ), PersistentTabConfig( screen: const SearchScreen(), item: ItemConfig( icon: AnimatedIconWrapper( icon: AnimatedIcons.search_ellipsis, ), title: 'Search', activeForegroundColor: Colors.indigo, ), ), ], navBarBuilder: (config) => Style1BottomNavBar(navBarConfig: config), ) ``` -------------------------------- ### Use AnimatedIconWrapper for Tab Icons Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/README.md Replace standard icons with AnimatedIconWrapper to enable automatic animations between tab states. Animation timings can also be adjusted. ```dart PersistentTabView( tabs: [ PersistentTabConfig( screen: const MainScreen(), item: ItemConfig( icon: AnimatedIconWrapper(icon: AnimatedIcons.home), // <- this also allows you to change animation timings. The animation itself will be triggered automatically title: "Home", ), ), ... ], navBarBuilder: (navBarConfig) => Style1BottomNavBar( navBarConfig: navBarConfig, ), ) ``` -------------------------------- ### Use Custom Navigation Bar Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/MigrationGuide.md The `PersistentTabView.custom` constructor is removed. Use the main constructor and the `navBarBuilder` parameter. Ensure `setState` is not called within `onItemSelected`; instead, call `navBarConfig.onItemSelected`. ```dart PersistentTabView.custom( ..., customWidget: (navBarEssentials) => CustomNavBarWidget( items: _navBarItems(), onItemSelected: (index) { setState(() { navBarEssentials .onItemSelected(index); }) }, selectedIndex: _controller.index, ) ), ``` ```dart PersistentTabView( ..., navBarBuilder: (navBarConfig) => CustomNavBarWidget( items: navBarConfig.items, onItemSelected: navBarConfig .onItemSelected, selectedIndex: navBarConfig .selectedIndex, ) ), ``` -------------------------------- ### Add Flutter Assemble Dependency Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/windows/runner/CMakeLists.txt Ensures that the Flutter tool's assembly process is completed before the main executable is built. This is a mandatory step for Flutter applications. ```cmake add_dependencies(${BINARY_NAME} flutter_assemble) ``` -------------------------------- ### Update NavBarDecoration in PersistentTabView Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/MigrationGuide.md Styles now receive `NavBarDecoration` directly. Move the `decoration` parameter from `PersistentTabView` to the `navBarBuilder`. ```dart PersistentTabView( ..., decoration: NavBarDecoration( color: Colors.green, ), ), ``` ```dart PersistentTabView( ..., navBarBuilder: (config) => Style1BottomNavBar( navBarConfig: config, navBarDecoration: NavBarDecoration( color: Colors.white, ), ), ), ``` -------------------------------- ### Control Tab Selection Programmatically Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt Manage tab selection and history using `PersistentTabController`. Initialize with `initialIndex` and `historyLength`, and remember to dispose of the controller. ```dart class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { // initialIndex: which tab is shown on first render // historyLength: how many tab switches are remembered for back navigation final _controller = PersistentTabController( initialIndex: 0, historyLength: 5, clearHistoryOnInitialIndex: true, ); @override void dispose() { _controller.dispose(); // required when you own the controller super.dispose(); } @override Widget build(BuildContext context) { return Column( children: [ ElevatedButton( onPressed: () => _controller.jumpToTab(2), // go to Settings child: const Text('Open Settings'), ), ElevatedButton( onPressed: () => _controller.jumpToPreviousTab(), // browser-back feel child: const Text('Go Back'), ), ElevatedButton( onPressed: () => _controller.openDrawer(), child: const Text('Open Drawer'), ), Expanded( child: PersistentTabView( controller: _controller, tabs: [ /* ... */ ], navBarBuilder: (config) => Style1BottomNavBar(navBarConfig: config), ), ), ], ); } } ``` -------------------------------- ### Add Badge/Notification Counter to Nav Item Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt Use the 'badges' package to overlay counters on navigation icons. Ensure the 'badges' package is added to your pubspec.yaml. The 'badgeContent' property takes a widget, typically a Text widget displaying the count. ```dart // pubspec.yaml: badges: ^3.0.0 PersistentTabConfig( screen: const InboxScreen(), item: ItemConfig( icon: Badge( badgeContent: Text( '3', style: const TextStyle(color: Colors.white, fontSize: 10), ), child: const Icon(Icons.notifications), ), inactiveIcon: Badge( showBadge: unreadCount > 0, badgeContent: Text( '$unreadCount', style: const TextStyle(color: Colors.white, fontSize: 10), ), child: const Icon(Icons.notifications_outlined), ), title: 'Inbox', activeForegroundColor: Colors.orange, ), ) ``` -------------------------------- ### Style Nav Bar with BoxDecoration and Blur Source: https://context7.com/jb3rndt/persistentbottomnavbarv2/llms.txt Customize the navigation bar's appearance using `NavBarDecoration`, which extends `BoxDecoration`. Supports frosted-glass effects with `ImageFilter.blur`. ```dart PersistentTabView( tabs: [ /* ... */ ], navBarBuilder: (navBarConfig) => Style2BottomNavBar( navBarConfig: navBarConfig, navBarDecoration: NavBarDecoration( color: Colors.white.withOpacity(0.85), borderRadius: const BorderRadius.vertical(top: Radius.circular(16)), boxShadow: const [ BoxShadow(color: Colors.black26, blurRadius: 12, offset: Offset(0, -2)), ], // Frosted-glass effect when color is semi-transparent filter: ImageFilter.blur(sigmaX: 8, sigmaY: 8), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), ), // Controls the animation of each nav bar item itemAnimationProperties: const ItemAnimation( duration: Duration(milliseconds: 300), curve: Curves.easeInOut, ), ), // Allow tab content to render behind the rounded nav bar navBarOverlap: const NavBarOverlap.full(), ) ``` -------------------------------- ### Basic PersistentTabView Usage Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/README.md Implement the PersistentTabView as the main container for your app's navigation, holding tab configurations and defining the navigation bar builder. It's recommended not to wrap this within a Scaffold's body. ```dart import 'package:flutter/material.dart'; import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart'; void main() => runApp(PersistenBottomNavBarDemo()); class PersistenBottomNavBarDemo extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Persistent Bottom Navigation Bar Demo', home: PersistentTabView( tabs: [ PersistentTabConfig( screen: YourFirstScreen(), item: ItemConfig( icon: Icon(Icons.home), title: "Home", ), ), PersistentTabConfig( screen: YourSecondScreen(), item: ItemConfig( icon: Icon(Icons.message), title: "Messages", ), ), PersistentTabConfig( screen: YourThirdScreen(), item: ItemConfig( icon: Icon(Icons.settings), title: "Settings", ), ), ], navBarBuilder: (navBarConfig) => Style1BottomNavBar( navBarConfig: navBarConfig, ), ), ); } } ``` -------------------------------- ### Switching PersistentTabView Styles Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/README.md Customize the navigation bar's appearance by replacing the default `navBarBuilder` with a different style, such as `Style2BottomNavBar`. Any predefined style or a custom widget can be used. ```dart PersistentTabView( tabs: ..., navBarBuilder: (navBarConfig) => Style2BottomNavBar( navBarConfig: navBarConfig, ), ) ``` -------------------------------- ### Initialize Flutter Service Worker Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/example/web/index.html This JavaScript code initializes the Flutter engine and its service worker. It's typically found in the main entry point of a Flutter web application. ```javascript const serviceWorkerVersion = null; window.addEventListener('load', function(ev) { // Download main.dart.js _flutter.loader.loadEntrypoint({ serviceWorker: { serviceWorkerVersion: serviceWorkerVersion, }, onEntrypointLoaded: function(engineInitializer) { engineInitializer.initializeEngine().then(function(appRunner) { appRunner.runApp(); }); } }); }); ``` -------------------------------- ### Push MaterialPageRoute with Navigation Bar Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/README.md Helper function to push a MaterialPageRoute onto the navigation stack while maintaining the visibility of the bottom navigation bar. ```dart pushWithNavBar( context, MaterialPageRoute(builder: (context) => ...) ); ``` -------------------------------- ### Push Screen Without Navigation Bar Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/README.md Utility function to push a new screen onto the navigation stack, hiding the bottom navigation bar. ```dart pushScreenWithoutNavBar( context, screen: MainScreen(), ); ``` -------------------------------- ### Migrate PersistentBottomNavBarItem Colors Source: https://github.com/jb3rndt/persistentbottomnavbarv2/blob/master/MigrationGuide.md Update color parameters from `activeColorPrimary`, `inactiveColorPrimary`, `activeColorSecondary`, `inactiveColorSecondary` to `activeForegroundColor`, `inactiveForegroundColor`, `activeBackgroundColor`, `inactiveBackgroundColor` respectively. Note the swap in roles between primary and secondary colors. ```dart PersistentBottomNavBarItem( ..., activeColorPrimary: Colors.red, inactiveColorPrimary: Colors.white, activeColorSecondary: Colors.blue, inactiveColorSecondary: Colors.grey, ), ``` ```dart ItemConfig( ..., activeForegroundColor: Colors.blue, inactiveForegroundColor: Colors.grey, activeBackgroundColor: Colors.red, inactiveBackgroundColor: Colors.white, ), ```