Skip to content

Instantly share code, notes, and snippets.

@osaxma
Last active November 24, 2021 14:50
Show Gist options
  • Save osaxma/2abfe803d44b2ebfd2f1563264005f01 to your computer and use it in GitHub Desktop.
Save osaxma/2abfe803d44b2ebfd2f1563264005f01 to your computer and use it in GitHub Desktop.
// ignore_for_file: constant_identifier_names
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routeInformationParser: _router.routeInformationParser,
routerDelegate: _router.routerDelegate,
title: 'Nested Navigation Example',
);
}
late final _router = GoRouter(
urlPathStrategy: UrlPathStrategy.path,
routes: [
GoRoute(
path: '/',
pageBuilder: (context, state) {
return MaterialPage(
key: state.pageKey,
child: const HomePage(),
);
},
routes: [
GoRoute(
path: 'profile',
redirect: (_) => '/profile/home',
),
GoRoute(
path: 'profile/:section',
pageBuilder: (context, state) {
final section = profileSectionfromString(state.params['section']!);
return MaterialPage(
key: state.pageKey,
child: ProfilePage(initialSection: section),
);
},
),
],
),
],
errorPageBuilder: (context, state) {
return MaterialPage(
key: state.pageKey,
child: ErrorPage(state.error),
);
},
);
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home Page'),
),
body: Center(
child: TextButton(
onPressed: () {
context.go('/profile');
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Icon(Icons.person),
Text(' Profile'),
],
),
),
),
);
}
}
class ProfilePage extends StatefulWidget {
final ProfileSections initialSection;
const ProfilePage({
Key? key,
required this.initialSection,
}) : super(key: key);
@override
_ProfilePageState createState() => _ProfilePageState();
}
class _ProfilePageState extends State<ProfilePage> with SingleTickerProviderStateMixin {
late final TabController _controller;
@override
void initState() {
// TODO: implement initState
super.initState();
_controller = TabController(
length: ProfileSections.values.length,
vsync: this,
initialIndex: widget.initialSection.index,
);
}
void _tap(int index) {
context.go('/profile/${ProfileSections.values[index].asString().toLowerCase()}');
}
@override
void didUpdateWidget(ProfilePage oldWidget) {
super.didUpdateWidget(oldWidget);
_controller.index = widget.initialSection.index;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Profile Page'),
bottom: TabBar(
controller: _controller,
tabs: [for (final section in ProfileSections.values) Tab(text: section.asString())],
onTap: (index) => _tap(index),
),
),
body: TabBarView(
controller: _controller,
children: [
for (final section in ProfileSections.values)
Center(
child: Text(section.asString()),
)
],
),
);
}
}
enum ProfileSections {
Home,
Likes,
Favourites,
Following,
}
ProfileSections profileSectionfromString(String string) {
return ProfileSections.values.firstWhere(
(element) => describeEnum(element).toLowerCase() == string.toLowerCase(),
orElse: () => ProfileSections.Home,
);
}
extension on ProfileSections {
String asString() => describeEnum(this);
}
/// sample error page
class ErrorPage extends StatelessWidget {
const ErrorPage(this.error, {Key? key}) : super(key: key);
final Exception? error;
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text('Page Not Found')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(error?.toString() ?? 'page not found'),
TextButton(
onPressed: () => context.go('/'),
child: const Text('Home '),
),
],
),
),
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment