Reputation: 11
Currently it only shows on main screens. I can only get it working on either ALL screens or only main screens... I need to be able to choose which screens to show the BottomNavigationBar on.
I now observe the routing in main.dart
and handle the rest of the navigation bar logic in a file I call NavigationConduit
.
I have a feeling the RouteObserver is not working properly, already not on the main screens... What am I doing wrong in this approach?
Is there a better way, without having to put code in every screen's initState
and dispose
?
This is my main.dart, reduced to only show related code:
import 'package:flutter/material.dart';
import 'package:app/navigation_conduit.dart';
import 'package:app/screens/profile/settings_1_overview.dart';
import 'package:app/screens/auth/change_password_1_current.dart';
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'App',
navigatorObservers: [routeObserver],
home: const NavigationConduit(),
routes: {
'/screens/profile/settings_1_overview': (context) => const SettingsOverview(),
'/screens/auth/change_password_1_current': (context) => const ChangePasswordScreen(),
},
);
}
}
And then this is my navigation_conduit.dart:
import 'package:flutter/material.dart';
import 'package:app/screens/home/home_screen.dart';
import 'package:app/screens/overview/overview.dart';
import 'package:app/screens/scanner/scanner.dart';
import 'package:app/screens/favorites/favorites_overview.dart';
import 'package:app/screens/profile/user_profile.dart';
import 'package:app/screens/profile/settings_1_overview.dart';
import 'package:app/screens/auth/change_password_1_current.dart';
class NavigationConduit extends StatefulWidget {
const NavigationConduit({super.key});
@override
_NavigationConduitState createState() => _NavigationConduitState();
}
class _NavigationConduitState extends State<NavigationConduit> with RouteAware {
int _selectedIndex = 0;
bool _showBottomNavBar = true;
final List<Widget> _screens = [
const HomeScreen(),
const Overview(),
const Scanner(),
const FavoritesOverview(),
const UserProfile(),
];
void _onItemTapped(int index) {
if (_selectedIndex == index) {
Navigator.of(context).popUntil((route) => route.isFirst);
} else {
setState(() {
_selectedIndex = index;
_showBottomNavBar = true;
});
}
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
final ModalRoute? route = ModalRoute.of(context);
setState(() {
_showBottomNavBar = _shouldShowBottomNavBar(route);
});
}
bool _shouldShowBottomNavBar(Route<dynamic>? route) {
if (route == null) return true;
final currentRouteName = route.settings.name ?? '';
print('Checking route: $currentRouteName');
return ![
'/screens/profile/settings_6_info',
'/screens/auth/change_password_1_current',
].contains(currentRouteName);
}
@override
void didPush() {
super.didPush();
setState(() {
_showBottomNavBar = _shouldShowBottomNavBar(ModalRoute.of(context));
});
}
@override
void didPopNext() {
super.didPopNext();
setState(() {
_showBottomNavBar = _shouldShowBottomNavBar(ModalRoute.of(context));
});
}
@override
void dispose() {
super.dispose();
}
String getIconAsset(int index, bool isSelected) {}
// This gets all the images connected to the right icons
@override
Widget build(BuildContext context) {
return Scaffold(
body: _screens[_selectedIndex],
bottomNavigationBar: _showBottomNavBar
? Container(
decoration: const BoxDecoration(
border: Border(
top: BorderSide(color: Color(0xFFA4A4A4), width: 1.0),
),
color: Colors.white,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: List.generate(5, (index) {
bool isSelected = _selectedIndex == index;
return IconButton(
icon: Image.asset(
getIconAsset(index, isSelected),
width: 24.0,
height: 24.0,
),
onPressed: () {
_onItemTapped(index);
},
);
}),
),
)
: null,
);
}
}
Upvotes: 1
Views: 71