Update active bar item while navigation
Opened this issue · 2 comments
Hello,
I am using Persistent Bottom Nav Bar in my project and I couldn't achieve a simple thing.
While navigating from one screen to another without using the bottom nav bar; I want to update the selected (active) nav bar item according to navigated page.
But I can not make it.
final Map<String, Widget Function(BuildContext)> appRouter = {
HomeScreen.routeName: (context) => const HomeScreen(),
StatisticsScreen.routeName: (context) => const StatisticsScreen(),
SettingsScreen.routeName: (context) => const SettingsScreen(),
};
List<PersistentBottomNavBarItem> _navBarsItems() {
return [
PersistentBottomNavBarItem(
icon: const Icon(CupertinoIcons.home),
title: (L.of(context).home),
activeColorPrimary: context.colors.tertiary,
inactiveColorPrimary: context.colors.onSurfaceVariant,
routeAndNavigatorSettings: RouteAndNavigatorSettings(
initialRoute: '/',
routes: appRouter,
),
),
PersistentBottomNavBarItem(
icon: const Icon(CupertinoIcons.chart_bar_alt_fill),
title: (L.of(context).statistics),
activeColorPrimary: context.colors.tertiary,
inactiveColorPrimary: context.colors.onSurfaceVariant,
routeAndNavigatorSettings: RouteAndNavigatorSettings(
initialRoute: '/',
routes: appRouter,
)),
PersistentBottomNavBarItem(
icon: const Icon(CupertinoIcons.settings),
title: (L.of(context).settings),
activeColorPrimary: context.colors.tertiary,
inactiveColorPrimary: context.colors.onSurfaceVariant,
routeAndNavigatorSettings: RouteAndNavigatorSettings(
initialRoute: '/',
routes: appRouter,
)),
];
}
@override
Widget build(BuildContext context) {
// Size size = MediaQuery.of(context).size;
return PersistentTabView(
context,
controller: _controller,
screens: widget._pages,
items: _navBarsItems(),
confineInSafeArea: true,
backgroundColor: context.colors.surface, // Default is Colors.white.
handleAndroidBackButtonPress: true, // Default is true.
resizeToAvoidBottomInset: true, // This needs to be true if you want to move up the screen when keyboard appears. Default is true.
stateManagement: true, // Default is true.
hideNavigationBarWhenKeyboardShows: true, // Recommended to set 'resizeToAvoidBottomInset' as true while using this argument. Default is true.
decoration: NavBarDecoration(borderRadius: BorderRadius.circular(10.0), colorBehindNavBar: context.colors.surface),
popAllScreensOnTapOfSelectedTab: true,
popActionScreens: PopActionScreensType.all,
itemAnimationProperties: const ItemAnimationProperties(
// Navigation Bar's items animation properties.
duration: Duration(milliseconds: 200),
curve: Curves.ease,
),
screenTransitionAnimation: const ScreenTransitionAnimation(
// Screen transition animation on change of selected tab.
animateTabTransition: true,
curve: Curves.ease,
duration: Duration(milliseconds: 200),
),
navBarStyle: NavBarStyle.style14, // Choose the nav bar style with this property.
);
}
In this example, I try to navigate from HomeScreen to SettingsScreen and I tried all the ways I know. But in the end, I can navigate successfully but the active navigation bar item is at the bottom nav bar still HomeScreen.
PersistentNavBarNavigator.pushNewScreenWithRouteSettings(
context,
settings: RouteSettings(name: SettingsScreen.routeName),
screen: SettingsScreen(),
withNavBar: true,
pageTransitionAnimation: PageTransitionAnimation.cupertino,
);
or
Navigator.of(context).pushNamed(SettingsScreen.routeName);
or
return PersistentNavBarNavigator.pushNewScreen(
this,
screen: SettingsScreen(),
withNavBar: true, // OPTIONAL VALUE. True by default.
pageTransitionAnimation: PageTransitionAnimation.cupertino,
);
What is the correct way of doing this?
Did you find a solution for this ?
Well, I was looking for a solution that I thought it was already integrated in the plugin, but since I couldn't find any, I manage to get this working just by having a callback.
So, lets say you have the following screens:
- Dashboard screen
- Posts screen
- Account screen
If in the Dashboard screen you wish to have a button to navigate to Account screen and keep the Navigation bar aligned, here's how you do it:
home_screen.dart
// Defines the initial index of screens
PersistentTabController tabController = PersistentTabController(initialIndex: 0);
// Create your persistentTabView normally
@override
Widget build(BuildContext context) {
return PersistentTabView(
controller: tabController,
screens: screens(),
... etc
);
}
List<Widget> screens() {
return [
DashboardScreen()
onScreenChanged: (int screenIndex) {
tabController.jumpToTab(screenIndex);
},
),
PostsScreen(),
AccountScreen(),
];
}
dashboard_screen.dart
class DashboardScreen extends StatefulWidget {
final void Function(int) onScreenChanged;
const DashboardScreen({
required this.onScreenChanged,
Key? key,
}) : super(key: key);
@override
_DashboardScreenState createState() => _DashboardScreenState();
}
class _DashboardScreenState extends State<DashboardScreen>
{
@override
Widget build(BuildContext context) {
return TextButton(
child: const Text('Go to account screen'),
onPressed: () => widget.onScreenChanged(2),
);
}
}