Skip to content

Instantly share code, notes, and snippets.

@slightfoot
Created May 4, 2022 18:05
Show Gist options
  • Select an option

  • Save slightfoot/2e889ad2c0dd231a860611b9ad8d6ae4 to your computer and use it in GitHub Desktop.

Select an option

Save slightfoot/2e889ad2c0dd231a860611b9ad8d6ae4 to your computer and use it in GitHub Desktop.
Bottom Nested Nav - by Simon Lightfoot :: #HumpdayQandA :: 4th May 2022
import 'package:flutter/material.dart';
void main() {
runApp(const App());
}
@immutable
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return FittedBox(
child: SizedBox(
width: 320,
height: 480,
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData.dark(),
home: const Main(),
),
),
);
}
}
@immutable
class Main extends StatefulWidget {
const Main({Key? key}) : super(key: key);
@override
State<Main> createState() => _MainState();
}
class _MainState extends State<Main> {
late List<GlobalKey<NavigatorState>> _navigatorKeys;
int _tabIndex = 0;
@override
void initState() {
super.initState();
_navigatorKeys = List.generate(4, (int index) {
return GlobalKey<NavigatorState>(debugLabel: 'nav_$index');
});
}
void _onBottomNavTapped(int index) {
setState(() => _tabIndex = index);
}
bool _onPopPage(Route<dynamic> route, dynamic result) {
// Dont pop the underlying page at the bottom of the stack.
return false;
}
Future<bool> _onBackPressed() async {
return !(await _navigatorKeys[_tabIndex].currentState!.maybePop());
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: _onBackPressed,
child: Scaffold(
body: IndexedStack(
index: _tabIndex,
children: [
Navigator(
key: _navigatorKeys[0],
onPopPage: _onPopPage,
pages: const [
MaterialPage(
key: ValueKey('home_page'),
child: Section(name: 'Home'),
),
],
),
Navigator(
key: _navigatorKeys[1],
onPopPage: _onPopPage,
pages: const [
MaterialPage(
key: ValueKey('android_page'),
child: Section(name: 'Android'),
),
],
),
Navigator(
key: _navigatorKeys[2],
onPopPage: _onPopPage,
pages: const [
MaterialPage(
key: ValueKey('delete_page'),
child: Section(
name: 'Delete',
),
),
],
),
Navigator(
key: _navigatorKeys[3],
onPopPage: _onPopPage,
pages: const [
MaterialPage(
key: ValueKey('save_page'),
child: Section(
name: 'Save',
),
),
],
),
],
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _tabIndex,
onTap: _onBottomNavTapped,
fixedColor: Colors.red,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.android),
label: 'Android',
),
BottomNavigationBarItem(
icon: Icon(Icons.delete),
label: 'Delete',
),
BottomNavigationBarItem(
icon: Icon(Icons.save),
label: 'Save',
),
],
),
),
);
}
}
@immutable
class Section extends StatelessWidget {
const Section({
Key? key,
required this.name,
this.index = 0,
}) : super(key: key);
final String name;
final int index;
static Route<void> route(String name, int index) {
return MaterialPageRoute(
settings: RouteSettings(name: '${name}_$index'),
builder: (_) {
return Section(name: name, index: index);
},
);
}
void _navigateTo(BuildContext context) {
Navigator.of(context).push(route(name, index + 1));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('$name $index'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('$name $index'),
TextButton(
onPressed: () => _navigateTo(context),
child: const Text('DO SOMETHING'),
),
],
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment