Jonny Borges
Committed by GitHub

Merge pull request #1644 from Bdaya-Dev/upmaster

Navigation fixes
import 'package:get/get.dart';
import '../controllers/dashboard_controller.dart';
class DashboardBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut<DashboardController>(
() => DashboardController(),
);
}
}
... ...
import 'dart:async';
import 'package:get/get.dart';
class DashboardController extends GetxController {
final now = DateTime.now().obs;
@override
void onReady() {
super.onReady();
Timer.periodic(
Duration(seconds: 1),
(timer) {
now.value = DateTime.now();
},
);
}
}
... ...
import 'package:example_nav2/app/modules/dashboard/controllers/dashboard_controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controllers/home_controller.dart';
import '../../home/controllers/home_controller.dart';
class DashboardView extends GetView<HomeController> {
class DashboardView extends GetView<DashboardController> {
@override
Widget build(BuildContext context) {
return Scaffold(
... ... @@ -16,7 +17,7 @@ class DashboardView extends GetView<HomeController> {
'DashboardView is working',
style: TextStyle(fontSize: 20),
),
Text('Time: ${controller.now.value.toString()}')
Text('Time: ${controller.now.value.toString()}'),
],
),
),
... ...
... ... @@ -2,16 +2,4 @@ import 'dart:async';
import 'package:get/get.dart';
class HomeController extends GetxController {
final now = DateTime.now().obs;
@override
void onReady() {
super.onReady();
Timer.periodic(
Duration(seconds: 1),
(timer) {
now.value = DateTime.now();
},
);
}
}
class HomeController extends GetxController {}
... ...
... ... @@ -3,7 +3,7 @@ import 'package:get/get.dart';
import '../../../routes/app_pages.dart';
import '../controllers/home_controller.dart';
import 'dashboard_view.dart';
import '../../dashboard/views/dashboard_view.dart';
class HomeView extends GetView<HomeController> {
@override
... ... @@ -22,7 +22,9 @@ class HomeView extends GetView<HomeController> {
return Scaffold(
body: GetRouterOutlet(
name: Routes.HOME,
emptyWidget: (delegate) => DashboardView(),
//It's preferable to use emptyPage instead of emptyWidget
emptyPage: (delegate) =>
Get.routeTree.matchRoute(Routes.DASHBOARD).route!,
pickPages: (currentNavStack) {
print('Home RouterOutlet: $currentNavStack');
... ... @@ -37,7 +39,7 @@ class HomeView extends GetView<HomeController> {
onTap: (value) {
switch (value) {
case 0:
delegate.until(Routes.HOME);
delegate.toNamed(Routes.HOME);
break;
case 1:
delegate.toNamed(Routes.PROFILE);
... ...
... ... @@ -12,26 +12,37 @@ class ProductsView extends GetView<ProductsController> {
onPressed: controller.loadDemoProductsFromSomeWhere,
label: Text('Add'),
),
body: Obx(
() => RefreshIndicator(
onRefresh: () async {
controller.products.clear();
controller.loadDemoProductsFromSomeWhere();
},
child: ListView.builder(
itemCount: controller.products.length,
itemBuilder: (context, index) {
final item = controller.products[index];
return ListTile(
onTap: () {
Get.rootDelegate.toNamed(Routes.PRODUCT_DETAILS(item.id));
body: Column(
children: [
Hero(
tag: 'heroLogo',
child: const FlutterLogo(),
),
Expanded(
child: Obx(
() => RefreshIndicator(
onRefresh: () async {
controller.products.clear();
controller.loadDemoProductsFromSomeWhere();
},
title: Text(item.name),
subtitle: Text(item.id),
);
},
child: ListView.builder(
itemCount: controller.products.length,
itemBuilder: (context, index) {
final item = controller.products[index];
return ListTile(
onTap: () {
Get.rootDelegate
.toNamed(Routes.PRODUCT_DETAILS(item.id));
},
title: Text(item.name),
subtitle: Text(item.id),
);
},
),
),
),
),
),
],
),
);
}
... ...
import 'package:example_nav2/app/routes/app_pages.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
... ... @@ -11,11 +12,16 @@ class ProfileView extends GetView<ProfileController> {
backgroundColor: Colors.amber,
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'ProfileView is working',
style: TextStyle(fontSize: 20),
),
Hero(
tag: 'heroLogo',
child: const FlutterLogo(),
),
MaterialButton(
child: Text('Show a test dialog'),
onPressed: () {
... ... @@ -25,6 +31,18 @@ class ProfileView extends GetView<ProfileController> {
barrierDismissible: true,
);
},
),
MaterialButton(
child: Text('Show a test dialog in Home router outlet'),
onPressed: () {
//shows a dialog
Get.defaultDialog(
title: 'Test Dialog In Home Outlet !!',
barrierDismissible: true,
navigatorKey: Get.nestedKey(Routes.HOME),
);
},
)
],
),
... ...
import 'package:get/get.dart';
import 'package:example_nav2/app/modules/dashboard/bindings/dashboard_binding.dart';
import 'package:example_nav2/app/modules/dashboard/views/dashboard_view.dart';
import '../middleware/auth_middleware.dart';
import '../modules/home/bindings/home_binding.dart';
import '../modules/home/views/home_view.dart';
... ... @@ -36,13 +39,11 @@ class AppPages {
//only enter this route when not authed
EnsureNotAuthedMiddleware(),
],
participatesInRootNavigator: false,
name: _Paths.LOGIN,
page: () => LoginView(),
binding: LoginBinding(),
),
GetPage(
participatesInRootNavigator: false,
preventDuplicates: true,
name: _Paths.HOME,
page: () => HomeView(),
... ... @@ -52,6 +53,11 @@ class AppPages {
title: null,
children: [
GetPage(
name: _Paths.DASHBOARD,
page: () => DashboardView(),
binding: DashboardBinding(),
),
GetPage(
middlewares: [
//only enter this route when authed
EnsureAuthMiddleware(),
... ... @@ -83,7 +89,6 @@ class AppPages {
],
),
GetPage(
participatesInRootNavigator: true,
name: _Paths.SETTINGS,
page: () => SettingsView(),
binding: SettingsBinding(),
... ...
... ... @@ -14,6 +14,7 @@ abstract class Routes {
static const LOGIN = _Paths.LOGIN;
static String LOGIN_THEN(String afterSuccessfulLogin) =>
'$LOGIN?then=${Uri.encodeQueryComponent(afterSuccessfulLogin)}';
static const DASHBOARD = _Paths.HOME + _Paths.DASHBOARD;
}
abstract class _Paths {
... ... @@ -23,4 +24,5 @@ abstract class _Paths {
static const SETTINGS = '/settings';
static const PRODUCT_DETAILS = '/:productId';
static const LOGIN = '/login';
static const DASHBOARD = '/dashboard';
}
... ...
... ... @@ -215,7 +215,7 @@ extension ExtensionDialog on GetInterface {
bool barrierDismissible = true,
Color? barrierColor,
bool useSafeArea = true,
bool useRootNavigator = true,
GlobalKey<NavigatorState>? navigatorKey,
Object? arguments,
Duration? transitionDuration,
Curve? transitionCurve,
... ... @@ -250,7 +250,7 @@ extension ExtensionDialog on GetInterface {
child: child,
);
},
useRootNavigator: useRootNavigator,
navigatorKey: navigatorKey,
routeSettings:
routeSettings ?? RouteSettings(arguments: arguments, name: name),
);
... ... @@ -264,20 +264,25 @@ extension ExtensionDialog on GetInterface {
Color barrierColor = const Color(0x80000000),
Duration transitionDuration = const Duration(milliseconds: 200),
RouteTransitionsBuilder? transitionBuilder,
bool useRootNavigator = true,
GlobalKey<NavigatorState>? navigatorKey,
RouteSettings? routeSettings,
}) {
assert(!barrierDismissible || barrierLabel != null);
return Navigator.of(overlayContext!, rootNavigator: useRootNavigator)
.push<T>(GetDialogRoute<T>(
pageBuilder: pageBuilder,
barrierDismissible: barrierDismissible,
barrierLabel: barrierLabel,
barrierColor: barrierColor,
transitionDuration: transitionDuration,
transitionBuilder: transitionBuilder,
settings: routeSettings,
));
final nav = navigatorKey?.currentState ??
Navigator.of(overlayContext!,
rootNavigator:
true); //overlay context will always return the root navigator
return nav.push<T>(
GetDialogRoute<T>(
pageBuilder: pageBuilder,
barrierDismissible: barrierDismissible,
barrierLabel: barrierLabel,
barrierColor: barrierColor,
transitionDuration: transitionDuration,
transitionBuilder: transitionBuilder,
settings: routeSettings,
),
);
}
/// Custom UI Dialog.
... ... @@ -309,6 +314,9 @@ extension ExtensionDialog on GetInterface {
// onWillPop Scope
WillPopCallback? onWillPop,
// the navigator used to push the dialog
GlobalKey<NavigatorState>? navigatorKey,
}) {
var leanCancel = onCancel != null || textCancel != null;
var leanConfirm = onConfirm != null || textConfirm != null;
... ... @@ -394,19 +402,15 @@ extension ExtensionDialog on GetInterface {
buttonPadding: EdgeInsets.zero,
);
if (onWillPop != null) {
return dialog<T>(
WillPopScope(
onWillPop: onWillPop,
child: baseAlertDialog,
),
barrierDismissible: barrierDismissible,
);
}
return dialog<T>(
baseAlertDialog,
onWillPop != null
? WillPopScope(
onWillPop: onWillPop,
child: baseAlertDialog,
)
: baseAlertDialog,
barrierDismissible: barrierDismissible,
navigatorKey: navigatorKey,
);
}
}
... ...
... ... @@ -263,7 +263,7 @@ class GetDelegate extends RouterDelegate<GetNavConfig>
if (currentHistory == null) return <GetPage>[];
final res = currentHistory.currentTreeBranch
.where((r) => r.participatesInRootNavigator);
.where((r) => r.participatesInRootNavigator != null);
if (res.length == 0) {
//default behavoir, all routes participate in root navigator
return currentHistory.currentTreeBranch;
... ... @@ -421,10 +421,13 @@ class GetNavigator extends Navigator {
bool reportsRouteUpdateToEngine = false,
TransitionDelegate? transitionDelegate,
String? name,
}) : assert(key != null || name != null,
'GetNavigator should either have a key or a name set'),
super(
key: key ?? Get.nestedKey(name),
}) : super(
//keys should be optional
key: key != null
? key
: name != null
? Get.nestedKey(name)
: null,
onPopPage: onPopPage ??
(route, result) {
final didPop = route.didPop(result);
... ...
... ... @@ -94,7 +94,7 @@ class GetRouterOutlet extends RouterOutlet<GetDelegate, GetNavConfig> {
GetPage Function(GetDelegate delegate)? emptyPage,
required List<GetPage> Function(GetNavConfig currentNavStack) pickPages,
bool Function(Route<dynamic>, dynamic)? onPopPage,
required String name,
String? name,
}) : assert(
(emptyPage == null && emptyWidget == null) ||
(emptyPage != null && emptyWidget == null) ||
... ... @@ -106,13 +106,6 @@ class GetRouterOutlet extends RouterOutlet<GetDelegate, GetNavConfig> {
(pages ?? <GetPage<dynamic>?>[emptyPage?.call(rDelegate)])
.whereType<GetPage<dynamic>>()
.toList();
final badPages = pageRes.where(
(element) => element.participatesInRootNavigator == true);
if (badPages.length > 0) {
throw """Pages in a router outlet shouldn't participate in the root navigator
$badPages""";
}
if (pageRes.length > 0) {
return GetNavigator(
onPopPage: onPopPage ??
... ...
... ... @@ -34,7 +34,7 @@ class GetPage<T> extends Page<T> {
final String? title;
final Transition? transition;
final Curve curve;
final bool participatesInRootNavigator;
final bool? participatesInRootNavigator;
final Alignment? alignment;
final bool maintainState;
final bool opaque;
... ... @@ -66,7 +66,7 @@ class GetPage<T> extends Page<T> {
required this.name,
required this.page,
this.title,
this.participatesInRootNavigator = true,
this.participatesInRootNavigator,
this.gestureWidth = 20,
// RouteSettings settings,
this.maintainState = true,
... ...