Skip to content

Instantly share code, notes, and snippets.

@daanporon
Created June 21, 2022 15:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daanporon/c57044894b71bbf6e7c121387d3a0b31 to your computer and use it in GitHub Desktop.
Save daanporon/c57044894b71bbf6e7c121387d3a0b31 to your computer and use it in GitHub Desktop.
Routemaster example with subnavigation and tabbed navigation
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:routemaster/routemaster.dart';
buildProductRoutes(String product) {
final routes = <String, PageBuilder>{};
routes['/home/$product'] = (_) => const Redirect('/home');
routes['/home/$product/:pid'] = (_) => CupertinoTabPage(
child: ScreenWithBottomNav(product: product),
paths: [
'/home/$product/:pid/tab-a',
'/home/$product/:pid/tab-b',
'/home/$product/:pid/tab-c'
],
);
routes['/home/$product/:pid/tab-a'] = (_) => const MaterialPage(
child: Screen(
name: 'Tab A',
key: ValueKey(
'A',
),
appBarEnabled: true,
appBarHome: true,
),
);
routes['/home/$product/:pid/tab-b'] = (_) => TabPage(
child: const ScreenWithTabs(),
paths: ['/home/$product/:pid/tab-b/1', '/home/$product/:pid/tab-b/2'],
);
routes['/home/$product/:pid/tab-b/1'] = (_) => const MaterialPage(
child: Screen(
name: 'B.1',
key: ValueKey(
'B.1',
),
),
);
routes['/home/$product/:pid/tab-b/2'] = (_) => const MaterialPage(
child: Screen(
name: 'B.2',
key: ValueKey(
'B.2',
),
),
);
routes['/home/$product/:pid/tab-c'] =
(_) => Redirect('/home/$product/:pid/tab-c/1');
routes['/home/$product/:pid/tab-c/1'] = (_) => MaterialPage(
child: Screen(
name: 'C.1',
appBarEnabled: true,
appBarHome: true,
key: const ValueKey(
'C.1',
),
onPressed: (context) => Routemaster.of(context).push('2'),
),
);
routes['/home/$product/:pid/tab-c/1/2'] = (_) => const MaterialPage(
child: Screen(
name: 'C.2',
appBarEnabled: true,
key: ValueKey(
'C.2',
),
),
);
return routes;
}
final RouteMap _routeMap = RouteMap(
routes: {
'/': (_) => const MaterialPage(child: StartScreen()),
'/home': (_) => const MaterialPage(child: HomeScreen()),
...buildProductRoutes('product-a'),
...buildProductRoutes('product-b'),
},
);
void main() {
runApp(const App());
}
class App extends StatelessWidget {
const App({
Key? key,
}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routerDelegate:
RoutemasterDelegate(routesBuilder: (context) => _routeMap),
routeInformationParser: const RoutemasterParser(),
);
}
}
class StartScreen extends StatelessWidget {
const StartScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Start page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
'/home',
'/home/product-a/1234/tab-b',
'/home/product-a/1234/tab-b/1',
'/home/product-a/1234/tab-b/2',
'/home/product-b/456/tab-c/1/2',
]
.map(
(route) => ElevatedButton(
onPressed: () => Routemaster.of(context).push(route),
child: Text(route),
),
)
.toList(),
),
),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () => Routemaster.of(context).push('product-a/1234'),
child: const Text('Product A'),
),
ElevatedButton(
onPressed: () => Routemaster.of(context).push('product-b/456'),
child: const Text('Product B'),
),
],
),
),
);
}
}
class ScreenWithBottomNav extends StatelessWidget {
final String product;
const ScreenWithBottomNav({
Key? key,
required this.product,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final tabState = CupertinoTabPage.of(context);
return CupertinoTabScaffold(
controller: tabState.controller,
tabBuilder: tabState.tabBuilder,
tabBar: CupertinoTabBar(
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.tab),
label: 'Tab A',
),
BottomNavigationBarItem(
icon: Icon(Icons.tab),
label: 'Tab B',
),
BottomNavigationBarItem(
icon: Icon(Icons.tab),
label: 'Tab C',
),
],
),
);
}
}
class Screen extends StatelessWidget {
final String name;
final bool appBarEnabled;
final bool appBarHome;
final void Function(BuildContext)? onPressed;
const Screen({
Key? key,
required this.name,
this.appBarEnabled = false,
this.appBarHome = false,
this.onPressed,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: appBarEnabled
? AppBar(
leading: appBarHome
? BackButton(
onPressed: () => Routemaster.of(context)
.popUntil((routeData) => routeData.path == '/home'),
)
: null,
)
: null,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(RouteData.of(context).path),
Text(RouteData.of(context).pathParameters.toString()),
Text(RouteData.of(context).queryParameters.toString()),
Text(appBarHome.toString()),
Text('Screen $name'),
if (onPressed != null)
ElevatedButton(
onPressed: () => onPressed?.call(context),
child: const Text('Press me'),
)
],
),
),
);
}
}
class ScreenWithTabs extends StatelessWidget {
const ScreenWithTabs({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final tabState = TabPage.of(context);
return Scaffold(
appBar: AppBar(
leading: BackButton(
onPressed: () => Routemaster.of(context)
.popUntil((routeData) => routeData.path == '/home'),
),
bottom: TabBar(
controller: tabState.controller,
tabs: const [
Tab(icon: Icon(Icons.tab), text: 'B1'),
Tab(icon: Icon(Icons.tab), text: 'B2'),
],
),
),
body: TabBarView(
controller: tabState.controller,
children: [
for (final stack in tabState.stacks) PageStackNavigator(stack: stack),
],
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment