Showing
7 changed files
with
180 additions
and
17 deletions
| 1 | # Get | 1 | # Get |
| 2 | 2 | ||
| 3 | -A consistent Flutter route navigation library that does not rebuild materialApp with each navigation. | 3 | +A consistent Flutter route navigation library that navigate with no context and not rebuild materialApp with each navigation. |
| 4 | 4 | ||
| 5 | ## Getting Started | 5 | ## Getting Started |
| 6 | 6 | ||
| 7 | Flutter's conventional navigation method has a route reconstruction bug that makes it inconsistent | 7 | Flutter's conventional navigation method has a route reconstruction bug that makes it inconsistent |
| 8 | for large applications with undefined routes. | 8 | for large applications with undefined routes. |
| 9 | Get came to solve this problem. | 9 | Get came to solve this problem. |
| 10 | - | ||
| 11 | -Plus, get makes navigation much clearer and more concise for beginners. The nomenclatures u | ||
| 12 | -sed by Flutter routes often confuse those who start with the framework. | ||
| 13 | -Get is friendly to those who came from Web programming, and those who never programmed, | ||
| 14 | -with a clearer navigation system. | 10 | +In addition, Get needs no context, also solving Flutter's biggest problem with patterns like BLoC. |
| 11 | +Get also makes navigation much clearer and more concise for beginners and friendly to those who came from Web programming. | ||
| 15 | 12 | ||
| 16 | ## How to use? | 13 | ## How to use? |
| 17 | 14 | ||
| 15 | +Add this to your package's pubspec.yaml file: | ||
| 16 | + | ||
| 17 | +dependencies: | ||
| 18 | + get: | ||
| 19 | + | ||
| 20 | +And import it: | ||
| 21 | +```dart | ||
| 22 | +import 'package:get/get.dart'; | ||
| 23 | +``` | ||
| 24 | +Add GetKey to your MaterialApp and enjoy: | ||
| 25 | +```dart | ||
| 26 | +MaterialApp( | ||
| 27 | + navigatorKey: Get.key, | ||
| 28 | + home: MyHome(), | ||
| 29 | + ) | ||
| 30 | +``` | ||
| 18 | To navigate to a new screen: | 31 | To navigate to a new screen: |
| 19 | 32 | ||
| 20 | ```dart | 33 | ```dart |
| 21 | -Get.to(context, NextScreen()); | 34 | +Get.to(NextScreen()); |
| 22 | ``` | 35 | ``` |
| 23 | 36 | ||
| 24 | To return to previous screen | 37 | To return to previous screen |
| 25 | 38 | ||
| 26 | ```dart | 39 | ```dart |
| 27 | -Get.back(context); | 40 | +Get.back(); |
| 28 | ``` | 41 | ``` |
| 29 | 42 | ||
| 30 | To go to the next screen and no option to go back to the previous screen (for use in SplashScreens, login screens and etc.) | 43 | To go to the next screen and no option to go back to the previous screen (for use in SplashScreens, login screens and etc.) |
| 31 | 44 | ||
| 32 | ```dart | 45 | ```dart |
| 33 | -Get.off(context, NextScreen()); | 46 | +Get.off(NextScreen()); |
| 34 | ``` | 47 | ``` |
| 35 | 48 | ||
| 36 | To go to the next screen and cancel all previous routes (useful in shopping carts, polls, and tests) | 49 | To go to the next screen and cancel all previous routes (useful in shopping carts, polls, and tests) |
| 37 | 50 | ||
| 38 | ```dart | 51 | ```dart |
| 39 | -Get.offAll(context, NextScreen()); | 52 | +Get.offAll(NextScreen()); |
| 40 | ``` | 53 | ``` |
| 41 | 54 | ||
| 42 | Is possible used default namedRoutes from flutter? | 55 | Is possible used default namedRoutes from flutter? |
| @@ -48,6 +61,7 @@ void main() { | @@ -48,6 +61,7 @@ void main() { | ||
| 48 | runApp(MaterialApp( | 61 | runApp(MaterialApp( |
| 49 | onGenerateRoute: Router.generateRoute, | 62 | onGenerateRoute: Router.generateRoute, |
| 50 | initialRoute: "/", | 63 | initialRoute: "/", |
| 64 | + navigatorKey: Get.key, | ||
| 51 | title: 'Navigation', | 65 | title: 'Navigation', |
| 52 | )); | 66 | )); |
| 53 | } | 67 | } |
| @@ -80,7 +94,7 @@ class FirstRoute extends StatelessWidget { | @@ -80,7 +94,7 @@ class FirstRoute extends StatelessWidget { | ||
| 80 | child: RaisedButton( | 94 | child: RaisedButton( |
| 81 | child: Text('Open route'), | 95 | child: Text('Open route'), |
| 82 | onPressed: () { | 96 | onPressed: () { |
| 83 | - Navigator.pushNamed(context, "/second"); | 97 | + Get.toNamed("/second"); |
| 84 | }, | 98 | }, |
| 85 | ), | 99 | ), |
| 86 | ), | 100 | ), |
| @@ -98,7 +112,7 @@ class SecondRoute extends StatelessWidget { | @@ -98,7 +112,7 @@ class SecondRoute extends StatelessWidget { | ||
| 98 | body: Center( | 112 | body: Center( |
| 99 | child: RaisedButton( | 113 | child: RaisedButton( |
| 100 | onPressed: () { | 114 | onPressed: () { |
| 101 | - Get.back(context); | 115 | + Get.back(); |
| 102 | }, | 116 | }, |
| 103 | child: Text('Go back!'), | 117 | child: Text('Go back!'), |
| 104 | ), | 118 | ), |
| @@ -4,6 +4,7 @@ import 'package:get/get.dart'; | @@ -4,6 +4,7 @@ import 'package:get/get.dart'; | ||
| 4 | void main() { | 4 | void main() { |
| 5 | runApp(MaterialApp( | 5 | runApp(MaterialApp( |
| 6 | title: 'Navigation Basics', | 6 | title: 'Navigation Basics', |
| 7 | + navigatorKey: Get.key, | ||
| 7 | home: FirstRoute(), | 8 | home: FirstRoute(), |
| 8 | )); | 9 | )); |
| 9 | } | 10 | } |
| @@ -19,7 +20,7 @@ class FirstRoute extends StatelessWidget { | @@ -19,7 +20,7 @@ class FirstRoute extends StatelessWidget { | ||
| 19 | child: RaisedButton( | 20 | child: RaisedButton( |
| 20 | child: Text('Open route'), | 21 | child: Text('Open route'), |
| 21 | onPressed: () { | 22 | onPressed: () { |
| 22 | - Get.to(context, SecondRoute()); | 23 | + Get.to(SecondRoute()); |
| 23 | }, | 24 | }, |
| 24 | ), | 25 | ), |
| 25 | ), | 26 | ), |
| @@ -37,7 +38,7 @@ class SecondRoute extends StatelessWidget { | @@ -37,7 +38,7 @@ class SecondRoute extends StatelessWidget { | ||
| 37 | body: Center( | 38 | body: Center( |
| 38 | child: RaisedButton( | 39 | child: RaisedButton( |
| 39 | onPressed: () { | 40 | onPressed: () { |
| 40 | - Get.back(context); | 41 | + Get.back(); |
| 41 | }, | 42 | }, |
| 42 | child: Text('Go back!'), | 43 | child: Text('Go back!'), |
| 43 | ), | 44 | ), |
lib/get.dart
0 → 100644
lib/src/getroute.dart
0 → 100644
| 1 | +import 'package:flutter/cupertino.dart'; | ||
| 2 | +import 'package:flutter/material.dart'; | ||
| 3 | + | ||
| 4 | +class GetRoute<T> extends PageRoute<T> { | ||
| 5 | + /// Construct a MaterialPageRoute whose contents are defined by [builder]. | ||
| 6 | + /// | ||
| 7 | + /// The values of [builder], [maintainState], and [fullScreenDialog] must not | ||
| 8 | + /// be null. | ||
| 9 | + GetRoute({ | ||
| 10 | + @required this.builder, | ||
| 11 | + RouteSettings settings, | ||
| 12 | + this.opaque = false, | ||
| 13 | + this.maintainState = true, | ||
| 14 | + bool fullscreenDialog = false, | ||
| 15 | + }) : assert(builder != null), | ||
| 16 | + assert(maintainState != null), | ||
| 17 | + assert(fullscreenDialog != null), | ||
| 18 | + assert(opaque != null), | ||
| 19 | + super(settings: settings, fullscreenDialog: fullscreenDialog); | ||
| 20 | + | ||
| 21 | + /// Builds the primary contents of the route. | ||
| 22 | + final WidgetBuilder builder; | ||
| 23 | + | ||
| 24 | + @override | ||
| 25 | + final bool maintainState; | ||
| 26 | + | ||
| 27 | + /// Allows you to set opaque to false to prevent route reconstruction. | ||
| 28 | + @override | ||
| 29 | + final bool opaque; | ||
| 30 | + | ||
| 31 | + @override | ||
| 32 | + Duration get transitionDuration => const Duration(milliseconds: 300); | ||
| 33 | + | ||
| 34 | + @override | ||
| 35 | + Color get barrierColor => null; | ||
| 36 | + | ||
| 37 | + @override | ||
| 38 | + String get barrierLabel => null; | ||
| 39 | + | ||
| 40 | + @override | ||
| 41 | + bool canTransitionFrom(TransitionRoute<dynamic> previousRoute) { | ||
| 42 | + return previousRoute is GetRoute || previousRoute is CupertinoPageRoute; | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + @override | ||
| 46 | + bool canTransitionTo(TransitionRoute<dynamic> nextRoute) { | ||
| 47 | + // Don't perform outgoing animation if the next route is a fullscreen dialog. | ||
| 48 | + return (nextRoute is GetRoute && !nextRoute.fullscreenDialog) | ||
| 49 | + || (nextRoute is CupertinoPageRoute && !nextRoute.fullscreenDialog); | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + @override | ||
| 53 | + Widget buildPage( | ||
| 54 | + BuildContext context, | ||
| 55 | + Animation<double> animation, | ||
| 56 | + Animation<double> secondaryAnimation, | ||
| 57 | + ) { | ||
| 58 | + final Widget result = builder(context); | ||
| 59 | + assert(() { | ||
| 60 | + if (result == null) { | ||
| 61 | + throw FlutterError.fromParts(<DiagnosticsNode>[ | ||
| 62 | + ErrorSummary('The builder for route "${settings.name}" returned null.'), | ||
| 63 | + ErrorDescription('Route builders must never return null.') | ||
| 64 | + ]); | ||
| 65 | + } | ||
| 66 | + return true; | ||
| 67 | + }()); | ||
| 68 | + return Semantics( | ||
| 69 | + scopesRoute: true, | ||
| 70 | + explicitChildNodes: true, | ||
| 71 | + child: result, | ||
| 72 | + ); | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + @override | ||
| 76 | + Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) { | ||
| 77 | + final PageTransitionsTheme theme = Theme.of(context).pageTransitionsTheme; | ||
| 78 | + return theme.buildTransitions<T>(this, context, animation, secondaryAnimation, child); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + @override | ||
| 82 | + String get debugLabel => '${super.debugLabel}(${settings.name})'; | ||
| 83 | +} |
lib/src/routes.dart
0 → 100644
| 1 | +import 'package:flutter/widgets.dart'; | ||
| 2 | +import 'getroute.dart'; | ||
| 3 | + | ||
| 4 | +class Get { | ||
| 5 | + static Get _get; | ||
| 6 | + static GlobalKey<NavigatorState> key = new GlobalKey<NavigatorState>(); | ||
| 7 | + | ||
| 8 | + factory Get() { | ||
| 9 | + if (_get == null) _get = Get._(); | ||
| 10 | + return _get; | ||
| 11 | + } | ||
| 12 | + | ||
| 13 | + Get._(); | ||
| 14 | + | ||
| 15 | + static to(Widget page, {bool rebuildRoutes = false}) { | ||
| 16 | + return key.currentState | ||
| 17 | + .push(GetRoute(opaque: rebuildRoutes, builder: (_) => page)); | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + static toNamed(String page, {arguments}) { | ||
| 21 | + return key.currentState.pushNamed(page, arguments: arguments); | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + static offNamed(String page, {arguments}) { | ||
| 25 | + return key.currentState | ||
| 26 | + .pushReplacementNamed(page, arguments: arguments); | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + static offAllNamed( | ||
| 30 | + String newRouteName, | ||
| 31 | + RoutePredicate predicate, { | ||
| 32 | + Object arguments, | ||
| 33 | + }) { | ||
| 34 | + return key.currentState | ||
| 35 | + .pushNamedAndRemoveUntil(newRouteName, predicate, arguments: arguments); | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + static back() { | ||
| 39 | + return key.currentState.pop(); | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + static off(Widget page, {bool rebuildRoutes = false}) { | ||
| 43 | + return key.currentState | ||
| 44 | + .pushReplacement(GetRoute(opaque: rebuildRoutes, builder: (_) => page)); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + static offAll(Widget page, RoutePredicate predicate, | ||
| 48 | + {bool rebuildRoutes = false}) { | ||
| 49 | + return key.currentState.pushAndRemoveUntil( | ||
| 50 | + GetRoute(opaque: rebuildRoutes, builder: (_) => page), predicate); | ||
| 51 | + } | ||
| 52 | +} |
| 1 | name: get | 1 | name: get |
| 2 | -description: A consistent Flutter route navigation library that does not rebuild materialApp with each navigation.. | ||
| 3 | -version: 1.1.0 | 2 | +description: A consistent Flutter route navigation library that navigate with no context and not rebuild materialApp with each navigation. |
| 3 | +version: 1.2.1 | ||
| 4 | author: Jonny Borges <jonataborges01@gmail.com> | 4 | author: Jonny Borges <jonataborges01@gmail.com> |
| 5 | homepage: https://github.com/jonataslaw/get | 5 | homepage: https://github.com/jonataslaw/get |
| 6 | 6 |
-
Please register or login to post a comment