Skip to content

Instantly share code, notes, and snippets.

@darkfrog26
Created April 22, 2021 03:00
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 darkfrog26/d39004a8b271764f2a4bacfe4ff2f3bc to your computer and use it in GitHub Desktop.
Save darkfrog26/d39004a8b271764f2a4bacfe4ff2f3bc to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class Screen {
final String key;
final Nav? nav;
final Widget Function() createWidget;
Screen({
required this.key,
this.nav,
required this.createWidget
});
String url() => '/$key';
}
class Nav {
final String label;
final IconData icon;
Nav(this.label, this.icon);
}
class Application extends StatelessWidget {
final String title;
final ThemeData theme;
final List<Screen> screens;
final List<Screen> navScreens;
final Map<String, Screen> urlMap;
final String initialURL;
late NavService navService;
Application({
required this.title,
required this.theme,
required this.screens
}) :
navScreens = screens.where((s) => s.nav != null).toList(),
urlMap = Map.fromIterable(screens, key: (s) => '/${s.key}', value: (s) => s),
initialURL = screens[0].url();
push(Screen screen) => navService.goToScreen(screen);
Widget build(BuildContext context) {
navService = NavService(this);
return GetMaterialApp(
title: title,
theme: theme,
initialBinding: BindingsBuilder.put(() => navService),
home: Home(initialURL: initialURL),
);
}
}
class NavService extends GetxService {
final Application app;
final activeIndex = 0.obs;
NavService(this.app);
@override
void onInit() {
ever(activeIndex, (int index) {
print('ActiveIndex changed: $activeIndex');
var url = app.navScreens[index].url();
Get.toNamed(url, id: 1);
});
super.onInit();
}
@override
void onClose() {
super.onClose();
}
void processRouting(Routing? route) {
print('ProcessRouting: ${route?.route?.settings.name}');
String url = route!.route!.settings.name!;
Screen? screen = app.urlMap[url];
if (screen != null) {
int index = app.navScreens.indexOf(screen);
if (index >= 0) {
activeIndex(index);
} else {
Get.to(screen.createWidget);
}
}
}
void goToScreen(Screen screen) => Get.toNamed(screen.url());
GetPageRoute onGenerateRoute(RouteSettings settings) {
final currentUrl = settings.name;
final screen = app.urlMap[currentUrl];
final GetPageBuilder page = () {
if (screen != null) {
return screen.createWidget();
} else {
return Center(child: Text('Error! No route for $currentUrl (${app.urlMap.keys})'));
}
};
return GetPageRoute(
routeName: currentUrl,
settings: settings,
page: page
);
}
}
class AppNavigatorObserver extends NavigatorObserver {
static int stack = 0;
@override
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
super.didPush(route, previousRoute);
if (route.settings.name != '/') {
stack++;
}
}
}
class Home extends GetWidget<NavService> {
final String _initialURL;
const Home({Key? key, required String initialURL}):
_initialURL = initialURL,
super(key: key);
@override
Widget build(BuildContext context) {
return WillPopScope(
child: Scaffold(
body: Navigator(
key: Get.nestedKey(1),
initialRoute: _initialURL,
observers: [
GetObserver(controller.processRouting, Get.routing),
AppNavigatorObserver()
],
onGenerateRoute: controller.onGenerateRoute,
),
bottomNavigationBar: Obx(
() => BottomNavigationBar(
currentIndex: controller.activeIndex(),
onTap: controller.activeIndex,
items: controller.app.navScreens
.map((s) => BottomNavigationBarItem(
icon: Icon(s.nav!.icon),
label: s.nav!.label
)
).toList(),
),
),
),
onWillPop: onWillPop
);
}
Future<bool> onWillPop() async {
AppNavigatorObserver.stack--;
if (AppNavigatorObserver.stack <= 0) {
AppNavigatorObserver.stack = 0;
return true;
} else {
Get.back(id: 1);
return false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment