Ahmed Fwela

added router outlet

  1 +{
  2 + // Use IntelliSense to learn about possible attributes.
  3 + // Hover to view descriptions of existing attributes.
  4 + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  5 + "version": "0.2.0",
  6 + "configurations": [
  7 + {
  8 + "name": "getx",
  9 + "request": "launch",
  10 + "type": "dart"
  11 + },
  12 + {
  13 + "name": "example",
  14 + "cwd": "example",
  15 + "request": "launch",
  16 + "type": "dart"
  17 + },
  18 + {
  19 + "name": "example_nav2",
  20 + "cwd": "example_nav2",
  21 + "request": "launch",
  22 + "type": "dart"
  23 + }
  24 + ]
  25 +}
1 import 'package:get/get.dart'; 1 import 'package:get/get.dart';
2 2
3 -class HomeController extends GetxController {  
4 - //TODO: Implement HomeController  
5 -  
6 - final count = 0.obs;  
7 - @override  
8 - void onInit() {  
9 - super.onInit();  
10 - }  
11 -  
12 - @override  
13 - void onReady() {  
14 - super.onReady();  
15 - }  
16 -  
17 - @override  
18 - void onClose() {}  
19 - void increment() => count.value++;  
20 -} 3 +class HomeController extends GetxController {}
  1 +import 'package:get/get.dart';
  2 +
  3 +import '../controllers/product_details_controller.dart';
  4 +
  5 +class ProductDetailsBinding extends Bindings {
  6 + @override
  7 + void dependencies() {
  8 + Get.lazyPut<ProductDetailsController>(
  9 + () => ProductDetailsController(),
  10 + );
  11 + }
  12 +}
  1 +import 'package:get/get.dart';
  2 +
  3 +class ProductDetailsController extends GetxController {}
  1 +import 'package:flutter/material.dart';
  2 +
  3 +import 'package:get/get.dart';
  4 +
  5 +import '../controllers/product_details_controller.dart';
  6 +
  7 +class ProductDetailsView extends GetView<ProductDetailsController> {
  8 + @override
  9 + Widget build(BuildContext context) {
  10 + return Scaffold(
  11 + appBar: AppBar(
  12 + title: Text('ProductDetailsView'),
  13 + centerTitle: true,
  14 + ),
  15 + body: Center(
  16 + child: Text(
  17 + 'ProductDetailsView is working',
  18 + style: TextStyle(fontSize: 20),
  19 + ),
  20 + ),
  21 + );
  22 + }
  23 +}
  1 +import 'package:get/get.dart';
  2 +
  3 +import '../controllers/profile_controller.dart';
  4 +
  5 +class ProfileBinding extends Bindings {
  6 + @override
  7 + void dependencies() {
  8 + Get.lazyPut<ProfileController>(
  9 + () => ProfileController(),
  10 + );
  11 + }
  12 +}
  1 +import 'package:get/get.dart';
  2 +
  3 +class ProfileController extends GetxController {
  4 + //TODO: Implement ProfileController
  5 +
  6 + final count = 0.obs;
  7 + @override
  8 + void onInit() {
  9 + super.onInit();
  10 + }
  11 +
  12 + @override
  13 + void onReady() {
  14 + super.onReady();
  15 + }
  16 +
  17 + @override
  18 + void onClose() {}
  19 + void increment() => count.value++;
  20 +}
  1 +import 'package:flutter/material.dart';
  2 +
  3 +import 'package:get/get.dart';
  4 +
  5 +import '../controllers/profile_controller.dart';
  6 +
  7 +class ProfileView extends GetView<ProfileController> {
  8 + @override
  9 + Widget build(BuildContext context) {
  10 + return Scaffold(
  11 + appBar: AppBar(
  12 + title: Text('ProfileView'),
  13 + centerTitle: true,
  14 + ),
  15 + body: Center(
  16 + child: Text(
  17 + 'ProfileView is working',
  18 + style: TextStyle(fontSize: 20),
  19 + ),
  20 + ),
  21 + );
  22 + }
  23 +}
  1 +import 'package:get/get.dart';
  2 +
  3 +import '../controllers/settings_controller.dart';
  4 +
  5 +class SettingsBinding extends Bindings {
  6 + @override
  7 + void dependencies() {
  8 + Get.lazyPut<SettingsController>(
  9 + () => SettingsController(),
  10 + );
  11 + }
  12 +}
  1 +import 'package:get/get.dart';
  2 +
  3 +class SettingsController extends GetxController {
  4 + //TODO: Implement SettingsController
  5 +
  6 + final count = 0.obs;
  7 + @override
  8 + void onInit() {
  9 + super.onInit();
  10 + }
  11 +
  12 + @override
  13 + void onReady() {
  14 + super.onReady();
  15 + }
  16 +
  17 + @override
  18 + void onClose() {}
  19 + void increment() => count.value++;
  20 +}
  1 +import 'package:flutter/material.dart';
  2 +
  3 +import 'package:get/get.dart';
  4 +
  5 +import '../controllers/settings_controller.dart';
  6 +
  7 +class SettingsView extends GetView<SettingsController> {
  8 + @override
  9 + Widget build(BuildContext context) {
  10 + return Scaffold(
  11 + appBar: AppBar(
  12 + title: Text('SettingsView'),
  13 + centerTitle: true,
  14 + ),
  15 + body: Center(
  16 + child: Text(
  17 + 'SettingsView is working',
  18 + style: TextStyle(fontSize: 20),
  19 + ),
  20 + ),
  21 + );
  22 + }
  23 +}
1 import 'package:get/get.dart'; 1 import 'package:get/get.dart';
2 2
3 -import 'package:example_nav2/app/modules/home/bindings/home_binding.dart';  
4 -import 'package:example_nav2/app/modules/home/views/home_view.dart';  
5 -import 'package:example_nav2/app/modules/products/bindings/products_binding.dart';  
6 -import 'package:example_nav2/app/modules/products/views/products_view.dart'; 3 +import '../modules/home/bindings/home_binding.dart';
  4 +import '../modules/home/views/home_view.dart';
  5 +import '../modules/product_details/bindings/product_details_binding.dart';
  6 +import '../modules/product_details/views/product_details_view.dart';
  7 +import '../modules/products/bindings/products_binding.dart';
  8 +import '../modules/products/views/products_view.dart';
  9 +import '../modules/profile/bindings/profile_binding.dart';
  10 +import '../modules/profile/views/profile_view.dart';
  11 +import '../modules/settings/bindings/settings_binding.dart';
  12 +import '../modules/settings/views/settings_view.dart';
7 13
8 part 'app_routes.dart'; 14 part 'app_routes.dart';
9 15
@@ -17,11 +23,30 @@ class AppPages { @@ -17,11 +23,30 @@ class AppPages {
17 name: _Paths.HOME, 23 name: _Paths.HOME,
18 page: () => HomeView(), 24 page: () => HomeView(),
19 binding: HomeBinding(), 25 binding: HomeBinding(),
  26 + children: [
  27 + GetPage(
  28 + name: _Paths.PROFILE,
  29 + page: () => ProfileView(),
  30 + binding: ProfileBinding(),
  31 + ),
  32 + ],
20 ), 33 ),
21 GetPage( 34 GetPage(
22 name: _Paths.PRODUCTS, 35 name: _Paths.PRODUCTS,
23 page: () => ProductsView(), 36 page: () => ProductsView(),
24 binding: ProductsBinding(), 37 binding: ProductsBinding(),
  38 + children: [
  39 + GetPage(
  40 + name: _Paths.PRODUCT_DETAILS,
  41 + page: () => ProductDetailsView(),
  42 + binding: ProductDetailsBinding(),
  43 + ),
  44 + ],
  45 + ),
  46 + GetPage(
  47 + name: _Paths.SETTINGS,
  48 + page: () => SettingsView(),
  49 + binding: SettingsBinding(),
25 ), 50 ),
26 ]; 51 ];
27 } 52 }
@@ -5,10 +5,18 @@ abstract class Routes { @@ -5,10 +5,18 @@ abstract class Routes {
5 Routes._(); 5 Routes._();
6 6
7 static const HOME = _Paths.HOME; 7 static const HOME = _Paths.HOME;
  8 + static const PROFILE = _Paths.PROFILE;
  9 +
  10 + static const SETTINGS = _Paths.SETTINGS;
  11 +
8 static const PRODUCTS = _Paths.PRODUCTS; 12 static const PRODUCTS = _Paths.PRODUCTS;
  13 + static PRODUCT_DETAILS(String productId) => '${_Paths.PRODUCTS}/$productId';
9 } 14 }
10 15
11 abstract class _Paths { 16 abstract class _Paths {
12 static const HOME = '/home'; 17 static const HOME = '/home';
13 static const PRODUCTS = '/products'; 18 static const PRODUCTS = '/products';
  19 + static const PROFILE = '/profile';
  20 + static const SETTINGS = '/settings';
  21 + static const PRODUCT_DETAILS = '/:productId';
14 } 22 }
@@ -8,6 +8,7 @@ environment: @@ -8,6 +8,7 @@ environment:
8 dependencies: 8 dependencies:
9 cupertino_icons: ^1.0.2 9 cupertino_icons: ^1.0.2
10 effective_dart: 1.3.1 10 effective_dart: 1.3.1
  11 + # get: ^4.1.4
11 get: 12 get:
12 path: ../ 13 path: ../
13 flutter: 14 flutter:
1 import 'package:flutter/widgets.dart'; 1 import 'package:flutter/widgets.dart';
2 -import 'package:get/get_navigation/src/nav2/get_router_delegate.dart'; 2 +import '../../get_navigation/src/nav2/get_router_delegate.dart';
  3 +import '../../get_navigation/src/routes/get_route.dart';
3 4
4 import 'log.dart'; 5 import 'log.dart';
5 import 'smart_management.dart'; 6 import 'smart_management.dart';
  1 +import 'package:flutter/widgets.dart';
  2 +
1 import '../../get_core/src/get_interface.dart'; 3 import '../../get_core/src/get_interface.dart';
2 4
3 import 'get_instance.dart'; 5 import 'get_instance.dart';
@@ -121,4 +123,8 @@ extension Inst on GetInterface { @@ -121,4 +123,8 @@ extension Inst on GetInterface {
121 /// [Get.lazyPut()], is registered in memory. 123 /// [Get.lazyPut()], is registered in memory.
122 /// - [tag] optional, if you use a [tag] to register the Instance. 124 /// - [tag] optional, if you use a [tag] to register the Instance.
123 bool isPrepared<S>({String? tag}) => GetInstance().isPrepared<S>(tag: tag); 125 bool isPrepared<S>({String? tag}) => GetInstance().isPrepared<S>(tag: tag);
  126 +
  127 + /// Casts the stored router delegate to a desired type
  128 + TDelegate? delegate<TDelegate extends RouterDelegate<TPage>, TPage>() =>
  129 + routerDelegate as TDelegate?;
124 } 130 }
  1 +import 'dart:js';
  2 +
  3 +import 'package:flutter/material.dart';
  4 +import '../../../get.dart';
  5 +
  6 +class RouterOutlet<TDelegate extends RouterDelegate<T>, T extends Object>
  7 + extends StatefulWidget {
  8 + final TDelegate routerDelegate;
  9 + final Widget Function(
  10 + BuildContext context,
  11 + TDelegate delegate,
  12 + T? currentRoute,
  13 + ) builder;
  14 +
  15 + //keys
  16 + RouterOutlet.builder({
  17 + TDelegate? delegate,
  18 + required this.builder,
  19 + }) : routerDelegate = delegate ?? Get.delegate<TDelegate, T>()!,
  20 + super();
  21 +
  22 + RouterOutlet({
  23 + TDelegate? delegate,
  24 + required List<T> Function(TDelegate routerDelegate) currentNavStack,
  25 + required List<T> Function(List<T> currentNavStack) pickPages,
  26 + required Widget Function(T? page) pageBuilder,
  27 + }) : this.builder(
  28 + builder: (context, rDelegate, currentConfig) {
  29 + final currentStack = currentNavStack(rDelegate);
  30 + final picked = pickPages(currentStack);
  31 + if (picked.length == 0) return pageBuilder(null);
  32 + return pageBuilder(picked.last);
  33 + },
  34 + delegate: delegate,
  35 + );
  36 + @override
  37 + _RouterOutletState<TDelegate, T> createState() =>
  38 + _RouterOutletState<TDelegate, T>();
  39 +}
  40 +
  41 +class _RouterOutletState<TDelegate extends RouterDelegate<T>, T extends Object>
  42 + extends State<RouterOutlet<TDelegate, T>> {
  43 + TDelegate get delegate => widget.routerDelegate;
  44 + @override
  45 + void initState() {
  46 + super.initState();
  47 + delegate.addListener(onRouterDelegateChanged);
  48 + }
  49 +
  50 + @override
  51 + void dispose() {
  52 + delegate.removeListener(onRouterDelegateChanged);
  53 + super.dispose();
  54 + }
  55 +
  56 + T? currentRoute;
  57 +
  58 + void onRouterDelegateChanged() {
  59 + setState(() {
  60 + currentRoute = delegate.currentConfiguration;
  61 + });
  62 + }
  63 +
  64 + @override
  65 + Widget build(BuildContext context) {
  66 + return widget.builder(context, delegate, currentRoute);
  67 + }
  68 +}