Skip to content

Instantly share code, notes, and snippets.

@BarryDaBee
Created December 24, 2021 21:58
Show Gist options
  • Save BarryDaBee/23f0072fd1aad22a828d087f88fa4d70 to your computer and use it in GitHub Desktop.
Save BarryDaBee/23f0072fd1aad22a828d087f88fa4d70 to your computer and use it in GitHub Desktop.
Implementation of nested navigation to persist bottom navbar across screens.
import 'package:flutter/material.dart';
void main() {
runApp(App());
}
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return const MaterialApp(home: Screen());
}
}
class Screen extends StatefulWidget {
const Screen({Key? key});
@override
State<Screen> createState() => _ScreenState();
}
class _ScreenState extends State<Screen> {
final GlobalKey _firstKey = GlobalKey<NavigatorState>();
final GlobalKey _secondKey = GlobalKey<NavigatorState>();
int _currentIndex = 0;
Widget _buildBody(int currentIndex) {
switch (currentIndex) {
case 0:
//Refactor the Navigator widgets into a seperateWidget if you can;
return Navigator(
onGenerateRoute: AppRouter.onGenerateRoute,
initialRoute: '/initial',
//onPopPage not necessary
onPopPage: (Route route, dynamic result) {
if (!route.didPop(result)) {
return false;
}
return true;
},
);
case 1:
return Navigator(
key: _firstKey,
onGenerateRoute: AppRouter.onGenerateRoute,
initialRoute: '/first',
onPopPage: (Route route, dynamic result) {
if (!route.didPop(result)) {
return false;
}
return true;
},
);
case 2:
return Navigator(
key: _secondKey,
onGenerateRoute: AppRouter.onGenerateRoute,
initialRoute: '/second',
onPopPage: (Route route, dynamic result) {
if (!route.didPop(result)) {
return false;
}
return true;
},
);
default:
return const Text('Page not found');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _buildBody(_currentIndex),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (int index) {
print(index);
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.add),
label: 'Add',
),
BottomNavigationBarItem(icon: Icon(Icons.cancel), label: 'Cancel'),
BottomNavigationBarItem(icon: Icon(Icons.close), label: 'Close'),
],
),
);
}
}
//No time to build mutiple screens to test.
class InfoScreen extends StatelessWidget {
final String message;
const InfoScreen({Key? key, required this.message});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
Navigator.pushNamed(context, '/second');
},
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
Navigator.pop(context);
},
child: Row(
children: const [
Text('Go back'),
Icon(Icons.arrow_back),
],
),
),
Text(message + " Click to go to next screen"),
],
),
),
);
}
}
class AppRouter {
static Route<dynamic> onGenerateRoute(RouteSettings settings) {
switch (settings.name) {
case '/initial':
return MaterialPageRoute(builder: (context) => const InfoScreen(message: 'Initial Screen')
);
case '/first':
return MaterialPageRoute(builder: (context) => const InfoScreen(message: 'First Screen Pushed')
);
case '/second':
return MaterialPageRoute(builder: (context) => const InfoScreen(message: 'Second Screen Pushed')
);
default:
return MaterialPageRoute(
builder: (context) => const InfoScreen(message: 'Unknown route'));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment