jonataslaw

Refactor GetRoute to add back gesture

@@ -172,6 +172,12 @@ @@ -172,6 +172,12 @@
172 ## [1.13.1-dev] 172 ## [1.13.1-dev]
173 - Fix back function 173 - Fix back function
174 174
  175 +## [1.14.0-dev]
  176 +- Added compatibility with Flutter 1.17.1
  177 +- Added back popGesture to iOS (default) and Android (optional)
  178 +- Improve performance
  179 +- Decrease lib size to 94.9kb (25.4k after compiled on release)
  180 +
175 181
176 182
177 183
@@ -11,7 +11,7 @@ increasing your productivity, and eliminating all the bugs present in Flutter's @@ -11,7 +11,7 @@ increasing your productivity, and eliminating all the bugs present in Flutter's
11 11
12 ##### If you use MODULAR, add on your MaterialApp this: navigatorKey: Get.addKey(Modular.navigatorKey) 12 ##### If you use MODULAR, add on your MaterialApp this: navigatorKey: Get.addKey(Modular.navigatorKey)
13 13
14 -##### If you use master/dev branch of Flutter, use the version 1.12.1-dev. 14 +##### If you use master/dev branch of Flutter, use the version 1.14.0-dev.
15 15
16 ## How to use? 16 ## How to use?
17 17
@@ -19,7 +19,7 @@ Add this to your package's pubspec.yaml file: @@ -19,7 +19,7 @@ Add this to your package's pubspec.yaml file:
19 19
20 ``` 20 ```
21 dependencies: 21 dependencies:
22 - get: ^1.11.6 // get: ^1.13.1-dev on dev/master 22 + get: ^1.11.6 // ^1.14.0-dev on dev/master
23 ``` 23 ```
24 24
25 And import it: 25 And import it:
@@ -268,7 +268,8 @@ class Router { @@ -268,7 +268,8 @@ class Router {
268 return GetRoute( 268 return GetRoute(
269 settings: settings, 269 settings: settings,
270 page: Third(), 270 page: Third(),
271 - transition: Transition.rightToLeft); 271 + popGesture: true,
  272 + transition: Transition.cupertino);
272 default: 273 default:
273 return GetRoute( 274 return GetRoute(
274 settings: settings, 275 settings: settings,
@@ -3,37 +3,37 @@ @@ -3,37 +3,37 @@
3 "packages": [ 3 "packages": [
4 { 4 {
5 "name": "archive", 5 "name": "archive",
6 - "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/archive-2.0.11", 6 + "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/archive-2.0.13",
7 "packageUri": "lib/", 7 "packageUri": "lib/",
8 "languageVersion": "2.0" 8 "languageVersion": "2.0"
9 }, 9 },
10 { 10 {
11 "name": "args", 11 "name": "args",
12 - "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/args-1.5.2", 12 + "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/args-1.6.0",
13 "packageUri": "lib/", 13 "packageUri": "lib/",
14 - "languageVersion": "2.0" 14 + "languageVersion": "2.3"
15 }, 15 },
16 { 16 {
17 "name": "async", 17 "name": "async",
18 - "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/async-2.4.0", 18 + "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/async-2.4.1",
19 "packageUri": "lib/", 19 "packageUri": "lib/",
20 - "languageVersion": "2.0" 20 + "languageVersion": "2.2"
21 }, 21 },
22 { 22 {
23 "name": "boolean_selector", 23 "name": "boolean_selector",
24 - "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.5", 24 + "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.0.0",
25 "packageUri": "lib/", 25 "packageUri": "lib/",
26 - "languageVersion": "2.0" 26 + "languageVersion": "2.4"
27 }, 27 },
28 { 28 {
29 "name": "charcode", 29 "name": "charcode",
30 - "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/charcode-1.1.2", 30 + "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/charcode-1.1.3",
31 "packageUri": "lib/", 31 "packageUri": "lib/",
32 - "languageVersion": "1.0" 32 + "languageVersion": "2.0"
33 }, 33 },
34 { 34 {
35 "name": "collection", 35 "name": "collection",
36 - "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/collection-1.14.11", 36 + "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/collection-1.14.12",
37 "packageUri": "lib/", 37 "packageUri": "lib/",
38 "languageVersion": "2.0" 38 "languageVersion": "2.0"
39 }, 39 },
@@ -45,7 +45,7 @@ @@ -45,7 +45,7 @@
45 }, 45 },
46 { 46 {
47 "name": "crypto", 47 "name": "crypto",
48 - "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/crypto-2.1.3", 48 + "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/crypto-2.1.4",
49 "packageUri": "lib/", 49 "packageUri": "lib/",
50 "languageVersion": "2.1" 50 "languageVersion": "2.1"
51 }, 51 },
@@ -75,7 +75,7 @@ @@ -75,7 +75,7 @@
75 }, 75 },
76 { 76 {
77 "name": "image", 77 "name": "image",
78 - "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/image-2.1.4", 78 + "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/image-2.1.12",
79 "packageUri": "lib/", 79 "packageUri": "lib/",
80 "languageVersion": "2.0" 80 "languageVersion": "2.0"
81 }, 81 },
@@ -105,7 +105,7 @@ @@ -105,7 +105,7 @@
105 }, 105 },
106 { 106 {
107 "name": "quiver", 107 "name": "quiver",
108 - "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/quiver-2.0.5", 108 + "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/quiver-2.1.3",
109 "packageUri": "lib/", 109 "packageUri": "lib/",
110 "languageVersion": "2.0" 110 "languageVersion": "2.0"
111 }, 111 },
@@ -117,9 +117,9 @@ @@ -117,9 +117,9 @@
117 }, 117 },
118 { 118 {
119 "name": "source_span", 119 "name": "source_span",
120 - "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/source_span-1.5.5", 120 + "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/source_span-1.7.0",
121 "packageUri": "lib/", 121 "packageUri": "lib/",
122 - "languageVersion": "1.8" 122 + "languageVersion": "2.6"
123 }, 123 },
124 { 124 {
125 "name": "stack_trace", 125 "name": "stack_trace",
@@ -165,9 +165,9 @@ @@ -165,9 +165,9 @@
165 }, 165 },
166 { 166 {
167 "name": "xml", 167 "name": "xml",
168 - "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/xml-3.5.0", 168 + "rootUri": "file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/xml-3.6.1",
169 "packageUri": "lib/", 169 "packageUri": "lib/",
170 - "languageVersion": "2.3" 170 + "languageVersion": "2.6"
171 }, 171 },
172 { 172 {
173 "name": "profileweb", 173 "name": "profileweb",
@@ -176,7 +176,7 @@ @@ -176,7 +176,7 @@
176 "languageVersion": "2.1" 176 "languageVersion": "2.1"
177 } 177 }
178 ], 178 ],
179 - "generated": "2020-03-30T23:54:30.607116Z", 179 + "generated": "2020-04-02T04:26:33.309754Z",
180 "generator": "pub", 180 "generator": "pub",
181 - "generatorVersion": "2.8.0-dev.17.0.flutter-1402e8e1a4" 181 + "generatorVersion": "2.8.0-dev.18.0.flutter-e8c4aed700"
182 } 182 }
1 -# Generated by pub on 2020-03-30 20:54:30.579731.  
2 -archive:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/archive-2.0.11/lib/  
3 -args:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/args-1.5.2/lib/  
4 -async:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/async-2.4.0/lib/  
5 -boolean_selector:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.5/lib/  
6 -charcode:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/charcode-1.1.2/lib/  
7 -collection:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/collection-1.14.11/lib/ 1 +# Generated by pub on 2020-04-02 01:26:33.285366.
  2 +archive:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/archive-2.0.13/lib/
  3 +args:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/args-1.6.0/lib/
  4 +async:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/async-2.4.1/lib/
  5 +boolean_selector:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.0.0/lib/
  6 +charcode:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/charcode-1.1.3/lib/
  7 +collection:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/collection-1.14.12/lib/
8 convert:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/convert-2.1.1/lib/ 8 convert:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/convert-2.1.1/lib/
9 -crypto:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/crypto-2.1.3/lib/ 9 +crypto:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/crypto-2.1.4/lib/
10 cupertino_icons:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/cupertino_icons-0.1.3/lib/ 10 cupertino_icons:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/cupertino_icons-0.1.3/lib/
11 flutter:file:///opt/flutter/packages/flutter/lib/ 11 flutter:file:///opt/flutter/packages/flutter/lib/
12 flutter_test:file:///opt/flutter/packages/flutter_test/lib/ 12 flutter_test:file:///opt/flutter/packages/flutter_test/lib/
13 get:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/get-1.11.6/lib/ 13 get:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/get-1.11.6/lib/
14 -image:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/image-2.1.4/lib/ 14 +image:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/image-2.1.12/lib/
15 matcher:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.6/lib/ 15 matcher:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.6/lib/
16 meta:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/meta-1.1.8/lib/ 16 meta:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/meta-1.1.8/lib/
17 path:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/path-1.6.4/lib/ 17 path:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/path-1.6.4/lib/
18 petitparser:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/petitparser-2.4.0/lib/ 18 petitparser:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/petitparser-2.4.0/lib/
19 -quiver:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/quiver-2.0.5/lib/ 19 +quiver:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/quiver-2.1.3/lib/
20 sky_engine:file:///opt/flutter/bin/cache/pkg/sky_engine/lib/ 20 sky_engine:file:///opt/flutter/bin/cache/pkg/sky_engine/lib/
21 -source_span:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/source_span-1.5.5/lib/ 21 +source_span:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/source_span-1.7.0/lib/
22 stack_trace:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.9.3/lib/ 22 stack_trace:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.9.3/lib/
23 stream_channel:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.0.0/lib/ 23 stream_channel:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.0.0/lib/
24 string_scanner:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.0.5/lib/ 24 string_scanner:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.0.5/lib/
@@ -26,5 +26,5 @@ term_glyph:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.1 @@ -26,5 +26,5 @@ term_glyph:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.1
26 test_api:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/test_api-0.2.15/lib/ 26 test_api:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/test_api-0.2.15/lib/
27 typed_data:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/typed_data-1.1.6/lib/ 27 typed_data:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/typed_data-1.1.6/lib/
28 vector_math:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/vector_math-2.0.8/lib/ 28 vector_math:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/vector_math-2.0.8/lib/
29 -xml:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/xml-3.5.0/lib/ 29 +xml:file:///opt/flutter/.pub-cache/hosted/pub.dartlang.org/xml-3.6.1/lib/
30 profileweb:lib/ 30 profileweb:lib/
@@ -7,42 +7,42 @@ packages: @@ -7,42 +7,42 @@ packages:
7 name: archive 7 name: archive
8 url: "https://pub.dartlang.org" 8 url: "https://pub.dartlang.org"
9 source: hosted 9 source: hosted
10 - version: "2.0.11" 10 + version: "2.0.13"
11 args: 11 args:
12 dependency: transitive 12 dependency: transitive
13 description: 13 description:
14 name: args 14 name: args
15 url: "https://pub.dartlang.org" 15 url: "https://pub.dartlang.org"
16 source: hosted 16 source: hosted
17 - version: "1.5.2" 17 + version: "1.6.0"
18 async: 18 async:
19 dependency: transitive 19 dependency: transitive
20 description: 20 description:
21 name: async 21 name: async
22 url: "https://pub.dartlang.org" 22 url: "https://pub.dartlang.org"
23 source: hosted 23 source: hosted
24 - version: "2.4.0" 24 + version: "2.4.1"
25 boolean_selector: 25 boolean_selector:
26 dependency: transitive 26 dependency: transitive
27 description: 27 description:
28 name: boolean_selector 28 name: boolean_selector
29 url: "https://pub.dartlang.org" 29 url: "https://pub.dartlang.org"
30 source: hosted 30 source: hosted
31 - version: "1.0.5" 31 + version: "2.0.0"
32 charcode: 32 charcode:
33 dependency: transitive 33 dependency: transitive
34 description: 34 description:
35 name: charcode 35 name: charcode
36 url: "https://pub.dartlang.org" 36 url: "https://pub.dartlang.org"
37 source: hosted 37 source: hosted
38 - version: "1.1.2" 38 + version: "1.1.3"
39 collection: 39 collection:
40 dependency: transitive 40 dependency: transitive
41 description: 41 description:
42 name: collection 42 name: collection
43 url: "https://pub.dartlang.org" 43 url: "https://pub.dartlang.org"
44 source: hosted 44 source: hosted
45 - version: "1.14.11" 45 + version: "1.14.12"
46 convert: 46 convert:
47 dependency: transitive 47 dependency: transitive
48 description: 48 description:
@@ -56,7 +56,7 @@ packages: @@ -56,7 +56,7 @@ packages:
56 name: crypto 56 name: crypto
57 url: "https://pub.dartlang.org" 57 url: "https://pub.dartlang.org"
58 source: hosted 58 source: hosted
59 - version: "2.1.3" 59 + version: "2.1.4"
60 cupertino_icons: 60 cupertino_icons:
61 dependency: "direct main" 61 dependency: "direct main"
62 description: 62 description:
@@ -87,7 +87,7 @@ packages: @@ -87,7 +87,7 @@ packages:
87 name: image 87 name: image
88 url: "https://pub.dartlang.org" 88 url: "https://pub.dartlang.org"
89 source: hosted 89 source: hosted
90 - version: "2.1.4" 90 + version: "2.1.12"
91 matcher: 91 matcher:
92 dependency: transitive 92 dependency: transitive
93 description: 93 description:
@@ -122,7 +122,7 @@ packages: @@ -122,7 +122,7 @@ packages:
122 name: quiver 122 name: quiver
123 url: "https://pub.dartlang.org" 123 url: "https://pub.dartlang.org"
124 source: hosted 124 source: hosted
125 - version: "2.0.5" 125 + version: "2.1.3"
126 sky_engine: 126 sky_engine:
127 dependency: transitive 127 dependency: transitive
128 description: flutter 128 description: flutter
@@ -134,7 +134,7 @@ packages: @@ -134,7 +134,7 @@ packages:
134 name: source_span 134 name: source_span
135 url: "https://pub.dartlang.org" 135 url: "https://pub.dartlang.org"
136 source: hosted 136 source: hosted
137 - version: "1.5.5" 137 + version: "1.7.0"
138 stack_trace: 138 stack_trace:
139 dependency: transitive 139 dependency: transitive
140 description: 140 description:
@@ -190,6 +190,6 @@ packages: @@ -190,6 +190,6 @@ packages:
190 name: xml 190 name: xml
191 url: "https://pub.dartlang.org" 191 url: "https://pub.dartlang.org"
192 source: hosted 192 source: hosted
193 - version: "3.5.0" 193 + version: "3.6.1"
194 sdks: 194 sdks:
195 - dart: ">=2.4.0 <3.0.0" 195 + dart: ">=2.6.0 <3.0.0"
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
2 import 'package:flutter/scheduler.dart'; 2 import 'package:flutter/scheduler.dart';
3 import 'package:get/src/dialog/dialog.dart'; 3 import 'package:get/src/dialog/dialog.dart';
4 import 'package:get/get.dart'; 4 import 'package:get/get.dart';
  5 +import 'platform/platform.dart';
5 import 'routes/blur/backdrop_blur.dart'; 6 import 'routes/blur/backdrop_blur.dart';
6 import 'routes/blur/transparent_route.dart'; 7 import 'routes/blur/transparent_route.dart';
7 import 'routes/default_route.dart'; 8 import 'routes/default_route.dart';
@@ -43,21 +44,27 @@ class Get { @@ -43,21 +44,27 @@ class Get {
43 44
44 /// It replaces Navigator.push, but needs no context, and it doesn't have the Navigator.push 45 /// It replaces Navigator.push, but needs no context, and it doesn't have the Navigator.push
45 /// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior 46 /// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior
46 - /// of rebuilding every app after a route, use rebuildRoutes = true as the parameter. 47 + /// of rebuilding every app after a route, use opaque = true as the parameter.
47 static Future<T> to<T>(Widget page, 48 static Future<T> to<T>(Widget page,
48 - {bool rebuildRoutes, Transition transition, Duration duration}) { 49 + {bool opaque,
  50 + Transition transition,
  51 + Duration duration,
  52 + bool popGesture}) {
49 // if (key.currentState.mounted) // add this if appear problems on future with route navigate 53 // if (key.currentState.mounted) // add this if appear problems on future with route navigate
50 // when widget don't mounted 54 // when widget don't mounted
51 return key.currentState.push(GetRoute( 55 return key.currentState.push(GetRoute(
52 - rebuildRoutes: rebuildRoutes, 56 + opaque: opaque ?? true,
53 page: page, 57 page: page,
54 - transition: transition ?? Transition.cupertino, 58 + popGesture: popGesture,
  59 + transition: transition ?? GetPlatform.isIOS
  60 + ? Transition.cupertino
  61 + : Transition.fade,
55 duration: duration ?? const Duration(milliseconds: 400))); 62 duration: duration ?? const Duration(milliseconds: 400)));
56 } 63 }
57 64
58 /// It replaces Navigator.pushNamed, but needs no context, and it doesn't have the Navigator.pushNamed 65 /// It replaces Navigator.pushNamed, but needs no context, and it doesn't have the Navigator.pushNamed
59 /// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior 66 /// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior
60 - /// of rebuilding every app after a route, use rebuildRoutes = true as the parameter. 67 + /// of rebuilding every app after a route, use opaque = true as the parameter.
61 static Future<T> toNamed<T>(String page, {arguments}) { 68 static Future<T> toNamed<T>(String page, {arguments}) {
62 // if (key.currentState.mounted) // add this if appear problems on future with route navigate 69 // if (key.currentState.mounted) // add this if appear problems on future with route navigate
63 // when widget don't mounted 70 // when widget don't mounted
@@ -128,27 +135,38 @@ class Get { @@ -128,27 +135,38 @@ class Get {
128 135
129 /// It replaces Navigator.pushReplacement, but needs no context, and it doesn't have the Navigator.pushReplacement 136 /// It replaces Navigator.pushReplacement, but needs no context, and it doesn't have the Navigator.pushReplacement
130 /// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior 137 /// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior
131 - /// of rebuilding every app after a route, use rebuildRoutes = true as the parameter. 138 + /// of rebuilding every app after a route, use opaque = true as the parameter.
132 static Future<T> off<T>(Widget page, 139 static Future<T> off<T>(Widget page,
133 - {bool rebuildRoutes = false, 140 + {bool opaque = false,
134 Transition transition, 141 Transition transition,
  142 + bool popGesture,
135 Duration duration = const Duration(milliseconds: 400)}) { 143 Duration duration = const Duration(milliseconds: 400)}) {
136 return key.currentState.pushReplacement(GetRoute( 144 return key.currentState.pushReplacement(GetRoute(
137 - rebuildRoutes: rebuildRoutes, 145 + opaque: opaque ?? true,
138 page: page, 146 page: page,
139 - transition: transition, 147 + popGesture: popGesture,
  148 + transition: transition ?? GetPlatform.isIOS
  149 + ? Transition.cupertino
  150 + : Transition.fade,
140 duration: duration)); 151 duration: duration));
141 } 152 }
142 153
143 /// It replaces Navigator.pushAndRemoveUntil, but needs no context 154 /// It replaces Navigator.pushAndRemoveUntil, but needs no context
144 static Future<T> offAll<T>(Widget page, 155 static Future<T> offAll<T>(Widget page,
145 {RoutePredicate predicate, 156 {RoutePredicate predicate,
146 - bool rebuildRoutes = false, 157 + bool opaque = false,
  158 + bool popGesture,
147 Transition transition}) { 159 Transition transition}) {
148 var route = (Route<dynamic> rota) => false; 160 var route = (Route<dynamic> rota) => false;
149 return key.currentState.pushAndRemoveUntil( 161 return key.currentState.pushAndRemoveUntil(
150 GetRoute( 162 GetRoute(
151 - rebuildRoutes: rebuildRoutes, page: page, transition: transition), 163 + opaque: opaque ?? true,
  164 + popGesture: popGesture,
  165 + page: page,
  166 + transition: transition ?? GetPlatform.isIOS
  167 + ? Transition.cupertino
  168 + : Transition.fade,
  169 + ),
152 predicate ?? route); 170 predicate ?? route);
153 } 171 }
154 172
  1 +import 'dart:math';
  2 +import 'dart:ui' show lerpDouble;
  3 +
  4 +import 'package:flutter/cupertino.dart';
  5 +import 'package:flutter/foundation.dart';
  6 +import 'package:flutter/gestures.dart';
1 import 'package:flutter/material.dart'; 7 import 'package:flutter/material.dart';
2 -import 'getroute_cupertino.dart';  
3 -import 'getroute_material.dart'; 8 +
  9 +import '../platform/platform.dart';
4 import 'transitions_type.dart'; 10 import 'transitions_type.dart';
5 -import 'package:get/get.dart';  
6 11
7 -// ignore: non_constant_identifier_names  
8 -PageRoute<T> GetRoute<T>({  
9 - Key key, 12 +const double _kBackGestureWidth = 20.0;
  13 +const double _kMinFlingVelocity = 1.0;
  14 +const int _kMaxDroppedSwipePageForwardAnimationTime = 800; // Milliseconds.
  15 +
  16 +// The maximum time for a page to get reset to it's original position if the
  17 +// user releases a page mid swipe.
  18 +const int _kMaxPageBackAnimationTime = 300;
  19 +
  20 +class GetRoute<T> extends PageRoute<T> {
  21 + /// Creates a page route for use in an iOS designed app.
  22 + ///
  23 + /// The [builder], [maintainState], and [fullscreenDialog] arguments must not
  24 + /// be null.
  25 + GetRoute({
  26 + @required this.page,
  27 + this.title,
10 RouteSettings settings, 28 RouteSettings settings,
11 - String title,  
12 - bool rebuildRoutes,  
13 - bool maintainState = true,  
14 - @required Widget page, 29 + this.maintainState = true,
  30 + this.curve = Curves.linear,
  31 + this.alignment,
  32 + this.opaque = true,
  33 + this.popGesture,
  34 + this.transition = Transition.cupertino,
  35 + this.duration = const Duration(milliseconds: 400),
  36 + bool fullscreenDialog = false,
  37 + }) : assert(page != null),
  38 + assert(maintainState != null),
  39 + assert(fullscreenDialog != null),
  40 + // assert(opaque),
  41 + super(settings: settings, fullscreenDialog: fullscreenDialog);
  42 +
  43 + /// Builds the primary contents of the route.
  44 + final Widget page;
  45 +
  46 + final bool popGesture;
  47 +
  48 + final Duration duration;
  49 +
  50 + final String title;
  51 +
  52 + final Transition transition;
  53 +
  54 + final Curve curve;
  55 +
  56 + final Alignment alignment;
  57 +
  58 + ValueNotifier<String> _previousTitle;
  59 +
  60 + /// The title string of the previous [GetRoute].
  61 + ///
  62 + /// The [ValueListenable]'s value is readable after the route is installed
  63 + /// onto a [Navigator]. The [ValueListenable] will also notify its listeners
  64 + /// if the value changes (such as by replacing the previous route).
  65 + ///
  66 + /// The [ValueListenable] itself will be null before the route is installed.
  67 + /// Its content value will be null if the previous route has no title or
  68 + /// is not a [GetRoute].
  69 + ///
  70 + /// See also:
  71 + ///
  72 + /// * [ValueListenableBuilder], which can be used to listen and rebuild
  73 + /// widgets based on a ValueListenable.
  74 + ValueListenable<String> get previousTitle {
  75 + assert(
  76 + _previousTitle != null,
  77 + 'Cannot read the previousTitle for a route that has not yet been installed',
  78 + );
  79 + return _previousTitle;
  80 + }
  81 +
  82 + @override
  83 + void didChangePrevious(Route<dynamic> previousRoute) {
  84 + final String previousTitleString =
  85 + previousRoute is GetRoute ? previousRoute.title : null;
  86 + if (_previousTitle == null) {
  87 + _previousTitle = ValueNotifier<String>(previousTitleString);
  88 + } else {
  89 + _previousTitle.value = previousTitleString;
  90 + }
  91 + super.didChangePrevious(previousRoute);
  92 + }
  93 +
  94 + @override
  95 + final bool maintainState;
  96 +
  97 + /// Allows you to set opaque to false to prevent route reconstruction.
  98 + @override
  99 + final bool opaque;
  100 +
  101 + @override
  102 + // A relatively rigorous eyeball estimation.
  103 + Duration get transitionDuration => const Duration(milliseconds: 400);
  104 +
  105 + @override
  106 + Color get barrierColor => null; //Color(0x00FFFFFF);
  107 +
  108 + @override
  109 + String get barrierLabel => null;
  110 +
  111 + @override
  112 + bool canTransitionTo(TransitionRoute<dynamic> nextRoute) {
  113 + // Don't perform outgoing animation if the next route is a fullscreen dialog.
  114 + return nextRoute is GetRoute && !nextRoute.fullscreenDialog;
  115 + }
  116 +
  117 + /// True if an iOS-style back swipe pop gesture is currently underway for [route].
  118 + ///
  119 + /// This just check the route's [NavigatorState.userGestureInProgress].
  120 + ///
  121 + /// See also:
  122 + ///
  123 + /// * [popGestureEnabled], which returns true if a user-triggered pop gesture
  124 + /// would be allowed.
  125 + static bool isPopGestureInProgress(PageRoute<dynamic> route) {
  126 + return route.navigator.userGestureInProgress;
  127 + }
  128 +
  129 + /// True if an iOS-style back swipe pop gesture is currently underway for this route.
  130 + ///
  131 + /// See also:
  132 + ///
  133 + /// * [isPopGestureInProgress], which returns true if a Cupertino pop gesture
  134 + /// is currently underway for specific route.
  135 + /// * [popGestureEnabled], which returns true if a user-triggered pop gesture
  136 + /// would be allowed.
  137 + bool get popGestureInProgress => isPopGestureInProgress(this);
  138 +
  139 + /// Whether a pop gesture can be started by the user.
  140 + ///
  141 + /// Returns true if the user can edge-swipe to a previous route.
  142 + ///
  143 + /// Returns false once [isPopGestureInProgress] is true, but
  144 + /// [isPopGestureInProgress] can only become true if [popGestureEnabled] was
  145 + /// true first.
  146 + ///
  147 + /// This should only be used between frames, not during build.
  148 + bool get popGestureEnabled => _isPopGestureEnabled(this);
  149 +
  150 + static bool _isPopGestureEnabled<T>(PageRoute<T> route) {
  151 + // If there's nothing to go back to, then obviously we don't support
  152 + // the back gesture.
  153 + if (route.isFirst) return false;
  154 + // If the route wouldn't actually pop if we popped it, then the gesture
  155 + // would be really confusing (or would skip internal routes), so disallow it.
  156 + if (route.willHandlePopInternally) return false;
  157 + // If attempts to dismiss this route might be vetoed such as in a page
  158 + // with forms, then do not allow the user to dismiss the route with a swipe.
  159 + if (route.hasScopedWillPopCallback) return false;
  160 + // Fullscreen dialogs aren't dismissible by back swipe.
  161 + if (route.fullscreenDialog) return false;
  162 + // If we're in an animation already, we cannot be manually swiped.
  163 + if (route.animation.status != AnimationStatus.completed) return false;
  164 + // If we're being popped into, we also cannot be swiped until the pop above
  165 + // it completes. This translates to our secondary animation being
  166 + // dismissed.
  167 + if (route.secondaryAnimation.status != AnimationStatus.dismissed)
  168 + return false;
  169 + // If we're in a gesture already, we cannot start another.
  170 + if (isPopGestureInProgress(route)) return false;
  171 +
  172 + // Looks like a back gesture would be welcome!
  173 + return true;
  174 + }
  175 +
  176 + @override
  177 + Widget buildPage(BuildContext context, Animation<double> animation,
  178 + Animation<double> secondaryAnimation) {
  179 + final Widget child = page;
  180 + final Widget result = Semantics(
  181 + scopesRoute: true,
  182 + explicitChildNodes: true,
  183 + child: child,
  184 + );
  185 + assert(() {
  186 + if (child == null) {
  187 + throw FlutterError.fromParts(<DiagnosticsNode>[
  188 + ErrorSummary(
  189 + 'The builder for route "${settings.name}" returned null.'),
  190 + ErrorDescription('Route builders must never return null.'),
  191 + ]);
  192 + }
  193 + return true;
  194 + }());
  195 + return result;
  196 + }
  197 +
  198 + // Called by _CupertinoBackGestureDetector when a pop ("back") drag start
  199 + // gesture is detected. The returned controller handles all of the subsequent
  200 + // drag events.
  201 + static _CupertinoBackGestureController<T> _startPopGesture<T>(
  202 + PageRoute<T> route) {
  203 + assert(_isPopGestureEnabled(route));
  204 +
  205 + return _CupertinoBackGestureController<T>(
  206 + navigator: route.navigator,
  207 + controller: route.controller, // protected access
  208 + );
  209 + }
  210 +
  211 + /// Returns a [CupertinoFullscreenDialogTransition] if [route] is a full
  212 + /// screen dialog, otherwise a [CupertinoPageTransition] is returned.
  213 + ///
  214 + /// Used by [GetRoute.buildTransitions].
  215 + ///
  216 + /// This method can be applied to any [PageRoute], not just
  217 + /// [GetRoute]. It's typically used to provide a Cupertino style
  218 + /// horizontal transition for material widgets when the target platform
  219 + /// is [TargetPlatform.iOS].
  220 + ///
  221 + /// See also:
  222 + ///
  223 + /// * [CupertinoPageTransitionsBuilder], which uses this method to define a
  224 + /// [PageTransitionsBuilder] for the [PageTransitionsTheme].
  225 + static Widget buildPageTransitions<T>(
  226 + PageRoute<T> route,
  227 + BuildContext context,
  228 + bool popGesture,
  229 + Animation<double> animation,
  230 + Animation<double> secondaryAnimation,
  231 + Widget child,
15 Transition transition, 232 Transition transition,
16 - Curve curve = Curves.linear, 233 + Curve curve,
17 Alignment alignment, 234 Alignment alignment,
18 - Duration duration = const Duration(milliseconds: 400),  
19 - bool fullscreenDialog = false,  
20 -}) {  
21 - return GetPlatform.isIOS  
22 - ? GetCupertino(  
23 - settings: settings,  
24 - title: title,  
25 - opaque: rebuildRoutes ?? true,  
26 - maintainState: maintainState,  
27 - page: page,  
28 - transition: transition ?? Transition.cupertino,  
29 - curve: curve, 235 + ) {
  236 + if (route.fullscreenDialog) {
  237 + final bool linearTransition = isPopGestureInProgress(route);
  238 + return CupertinoFullscreenDialogTransition(
  239 + primaryRouteAnimation: animation,
  240 + secondaryRouteAnimation: secondaryAnimation,
  241 + child: child,
  242 + linearTransition: linearTransition,
  243 + );
  244 + } else {
  245 + switch (transition) {
  246 + case Transition.fade:
  247 + final PageTransitionsBuilder matchingBuilder =
  248 + FadeUpwardsPageTransitionsBuilder();
  249 + return matchingBuilder.buildTransitions<T>(
  250 + route,
  251 + context,
  252 + animation,
  253 + secondaryAnimation,
  254 + popGesture
  255 + ? _CupertinoBackGestureDetector<T>(
  256 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  257 + onStartPopGesture: () => _startPopGesture<T>(route),
  258 + child: child)
  259 + : child);
  260 + break;
  261 + case Transition.rightToLeft:
  262 + return SlideTransition(
  263 + transformHitTests: false,
  264 + position: new Tween<Offset>(
  265 + begin: const Offset(1.0, 0.0),
  266 + end: Offset.zero,
  267 + ).animate(animation),
  268 + child: new SlideTransition(
  269 + position: new Tween<Offset>(
  270 + begin: Offset.zero,
  271 + end: const Offset(-1.0, 0.0),
  272 + ).animate(secondaryAnimation),
  273 + child: popGesture
  274 + ? _CupertinoBackGestureDetector<T>(
  275 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  276 + onStartPopGesture: () => _startPopGesture<T>(route),
  277 + child: child)
  278 + : child),
  279 + );
  280 + break;
  281 + case Transition.leftToRight:
  282 + return SlideTransition(
  283 + transformHitTests: false,
  284 + position: Tween<Offset>(
  285 + begin: const Offset(-1.0, 0.0),
  286 + end: Offset.zero,
  287 + ).animate(animation),
  288 + child: new SlideTransition(
  289 + position: new Tween<Offset>(
  290 + begin: Offset.zero,
  291 + end: const Offset(1.0, 0.0),
  292 + ).animate(secondaryAnimation),
  293 + child: popGesture
  294 + ? _CupertinoBackGestureDetector<T>(
  295 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  296 + onStartPopGesture: () => _startPopGesture<T>(route),
  297 + child: child)
  298 + : child),
  299 + );
  300 + break;
  301 + case Transition.upToDown:
  302 + return SlideTransition(
  303 + transformHitTests: false,
  304 + position: Tween<Offset>(
  305 + begin: const Offset(0.0, -1.0),
  306 + end: Offset.zero,
  307 + ).animate(animation),
  308 + child: new SlideTransition(
  309 + position: new Tween<Offset>(
  310 + begin: Offset.zero,
  311 + end: const Offset(0.0, 1.0),
  312 + ).animate(secondaryAnimation),
  313 + child: popGesture
  314 + ? _CupertinoBackGestureDetector<T>(
  315 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  316 + onStartPopGesture: () => _startPopGesture<T>(route),
  317 + child: child)
  318 + : child),
  319 + );
  320 + break;
  321 + case Transition.downToUp:
  322 + return SlideTransition(
  323 + transformHitTests: false,
  324 + position: Tween<Offset>(
  325 + begin: const Offset(0.0, 1.0),
  326 + end: Offset.zero,
  327 + ).animate(animation),
  328 + child: new SlideTransition(
  329 + position: new Tween<Offset>(
  330 + begin: Offset.zero,
  331 + end: const Offset(0.0, -1.0),
  332 + ).animate(secondaryAnimation),
  333 + child: popGesture
  334 + ? _CupertinoBackGestureDetector<T>(
  335 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  336 + onStartPopGesture: () => _startPopGesture<T>(route),
  337 + child: child)
  338 + : child),
  339 + );
  340 + break;
  341 + case Transition.scale:
  342 + return ScaleTransition(
30 alignment: alignment, 343 alignment: alignment,
31 - duration: duration,  
32 - fullscreenDialog: fullscreenDialog)  
33 - : GetMaterial(  
34 - settings: settings,  
35 - opaque: rebuildRoutes ?? false,  
36 - maintainState: maintainState,  
37 - page: page,  
38 - transition: transition ?? Transition.fade, 344 + scale: CurvedAnimation(
  345 + parent: animation,
  346 + curve: Interval(
  347 + 0.00,
  348 + 0.50,
39 curve: curve, 349 curve: curve,
  350 + ),
  351 + ),
  352 + child: popGesture
  353 + ? _CupertinoBackGestureDetector<T>(
  354 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  355 + onStartPopGesture: () => _startPopGesture<T>(route),
  356 + child: child)
  357 + : child);
  358 + break;
  359 + case Transition.rotate:
  360 + return RotationTransition(
40 alignment: alignment, 361 alignment: alignment,
41 - duration: duration,  
42 - fullscreenDialog: fullscreenDialog); 362 + turns: animation,
  363 + child: ScaleTransition(
  364 + alignment: alignment,
  365 + scale: animation,
  366 + child: FadeTransition(
  367 + opacity: animation,
  368 + child: popGesture
  369 + ? _CupertinoBackGestureDetector<T>(
  370 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  371 + onStartPopGesture: () => _startPopGesture<T>(route),
  372 + child: child)
  373 + : child),
  374 + ),
  375 + );
  376 + break;
  377 +
  378 + case Transition.rightToLeftWithFade:
  379 + return SlideTransition(
  380 + position: Tween<Offset>(
  381 + begin: const Offset(1.0, 0.0),
  382 + end: Offset.zero,
  383 + ).animate(animation),
  384 + child: FadeTransition(
  385 + opacity: animation,
  386 + child: SlideTransition(
  387 + position: Tween<Offset>(
  388 + begin: Offset.zero,
  389 + end: const Offset(-1.0, 0.0),
  390 + ).animate(secondaryAnimation),
  391 + child: popGesture
  392 + ? _CupertinoBackGestureDetector<T>(
  393 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  394 + onStartPopGesture: () => _startPopGesture<T>(route),
  395 + child: child)
  396 + : child),
  397 + ),
  398 + );
  399 + break;
  400 + case Transition.leftToRightWithFade:
  401 + return SlideTransition(
  402 + position: Tween<Offset>(
  403 + begin: const Offset(-1.0, 0.0),
  404 + end: Offset.zero,
  405 + ).animate(animation),
  406 + child: FadeTransition(
  407 + opacity: animation,
  408 + child: SlideTransition(
  409 + position: Tween<Offset>(
  410 + begin: Offset.zero,
  411 + end: const Offset(1.0, 0.0),
  412 + ).animate(secondaryAnimation),
  413 + child: popGesture
  414 + ? _CupertinoBackGestureDetector<T>(
  415 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  416 + onStartPopGesture: () => _startPopGesture<T>(route),
  417 + child: child)
  418 + : child),
  419 + ),
  420 + );
  421 + break;
  422 + case Transition.cupertino:
  423 + return CupertinoPageTransition(
  424 + primaryRouteAnimation: animation,
  425 + secondaryRouteAnimation: secondaryAnimation,
  426 + // Check if the route has an animation that's currently participating
  427 + // in a back swipe gesture.
  428 + //
  429 + // In the middle of a back gesture drag, let the transition be linear to
  430 + // match finger motions.
  431 + linearTransition: isPopGestureInProgress(route),
  432 + child: _CupertinoBackGestureDetector<T>(
  433 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  434 + onStartPopGesture: () => _startPopGesture<T>(route),
  435 + child: child,
  436 + ),
  437 + );
  438 + break;
  439 + default:
  440 + return CupertinoPageTransition(
  441 + primaryRouteAnimation: animation,
  442 + secondaryRouteAnimation: secondaryAnimation,
  443 + // Check if the route has an animation that's currently participating
  444 + // in a back swipe gesture.
  445 + //
  446 + // In the middle of a back gesture drag, let the transition be linear to
  447 + // match finger motions.
  448 + linearTransition: isPopGestureInProgress(route),
  449 + child: popGesture
  450 + ? _CupertinoBackGestureDetector<T>(
  451 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  452 + onStartPopGesture: () => _startPopGesture<T>(route),
  453 + child: child)
  454 + : child,
  455 + );
  456 + }
  457 + }
  458 + }
  459 +
  460 + @override
  461 + Widget buildTransitions(BuildContext context, Animation<double> animation,
  462 + Animation<double> secondaryAnimation, Widget child) {
  463 + return buildPageTransitions<T>(
  464 + this,
  465 + context,
  466 + popGesture ?? GetPlatform.isIOS,
  467 + animation,
  468 + secondaryAnimation,
  469 + child,
  470 + transition,
  471 + curve,
  472 + alignment);
  473 + }
  474 +
  475 + @override
  476 + String get debugLabel => '${super.debugLabel}(${settings.name})';
  477 +}
  478 +
  479 +class _CupertinoBackGestureDetector<T> extends StatefulWidget {
  480 + const _CupertinoBackGestureDetector({
  481 + Key key,
  482 + @required this.enabledCallback,
  483 + @required this.onStartPopGesture,
  484 + @required this.child,
  485 + }) : assert(enabledCallback != null),
  486 + assert(onStartPopGesture != null),
  487 + assert(child != null),
  488 + super(key: key);
  489 +
  490 + final Widget child;
  491 +
  492 + final ValueGetter<bool> enabledCallback;
  493 +
  494 + final ValueGetter<_CupertinoBackGestureController<T>> onStartPopGesture;
  495 +
  496 + @override
  497 + _CupertinoBackGestureDetectorState<T> createState() =>
  498 + _CupertinoBackGestureDetectorState<T>();
  499 +}
  500 +
  501 +class _CupertinoBackGestureDetectorState<T>
  502 + extends State<_CupertinoBackGestureDetector<T>> {
  503 + _CupertinoBackGestureController<T> _backGestureController;
  504 +
  505 + HorizontalDragGestureRecognizer _recognizer;
  506 +
  507 + @override
  508 + void initState() {
  509 + super.initState();
  510 + _recognizer = HorizontalDragGestureRecognizer(debugOwner: this)
  511 + ..onStart = _handleDragStart
  512 + ..onUpdate = _handleDragUpdate
  513 + ..onEnd = _handleDragEnd
  514 + ..onCancel = _handleDragCancel;
  515 + }
  516 +
  517 + @override
  518 + void dispose() {
  519 + _recognizer.dispose();
  520 + super.dispose();
  521 + }
  522 +
  523 + void _handleDragStart(DragStartDetails details) {
  524 + assert(mounted);
  525 + assert(_backGestureController == null);
  526 + _backGestureController = widget.onStartPopGesture();
  527 + }
  528 +
  529 + void _handleDragUpdate(DragUpdateDetails details) {
  530 + assert(mounted);
  531 + assert(_backGestureController != null);
  532 + _backGestureController.dragUpdate(
  533 + _convertToLogical(details.primaryDelta / context.size.width));
  534 + }
  535 +
  536 + void _handleDragEnd(DragEndDetails details) {
  537 + assert(mounted);
  538 + assert(_backGestureController != null);
  539 + _backGestureController.dragEnd(_convertToLogical(
  540 + details.velocity.pixelsPerSecond.dx / context.size.width));
  541 + _backGestureController = null;
  542 + }
  543 +
  544 + void _handleDragCancel() {
  545 + assert(mounted);
  546 + // This can be called even if start is not called, paired with the "down" event
  547 + // that we don't consider here.
  548 + _backGestureController?.dragEnd(0.0);
  549 + _backGestureController = null;
  550 + }
  551 +
  552 + void _handlePointerDown(PointerDownEvent event) {
  553 + if (widget.enabledCallback()) _recognizer.addPointer(event);
  554 + }
  555 +
  556 + double _convertToLogical(double value) {
  557 + switch (Directionality.of(context)) {
  558 + case TextDirection.rtl:
  559 + return -value;
  560 + case TextDirection.ltr:
  561 + return value;
  562 + }
  563 + return null;
  564 + }
  565 +
  566 + @override
  567 + Widget build(BuildContext context) {
  568 + assert(debugCheckHasDirectionality(context));
  569 + // For devices with notches, the drag area needs to be larger on the side
  570 + // that has the notch.
  571 + double dragAreaWidth = Directionality.of(context) == TextDirection.ltr
  572 + ? MediaQuery.of(context).padding.left
  573 + : MediaQuery.of(context).padding.right;
  574 + dragAreaWidth = max(dragAreaWidth, _kBackGestureWidth);
  575 + return Stack(
  576 + fit: StackFit.passthrough,
  577 + children: <Widget>[
  578 + widget.child,
  579 + PositionedDirectional(
  580 + start: 0.0,
  581 + width: dragAreaWidth,
  582 + top: 0.0,
  583 + bottom: 0.0,
  584 + child: Listener(
  585 + onPointerDown: _handlePointerDown,
  586 + behavior: HitTestBehavior.translucent,
  587 + ),
  588 + ),
  589 + ],
  590 + );
  591 + }
  592 +}
  593 +
  594 +class _CupertinoBackGestureController<T> {
  595 + /// Creates a controller for an iOS-style back gesture.
  596 + ///
  597 + /// The [navigator] and [controller] arguments must not be null.
  598 + _CupertinoBackGestureController({
  599 + @required this.navigator,
  600 + @required this.controller,
  601 + }) : assert(navigator != null),
  602 + assert(controller != null) {
  603 + navigator.didStartUserGesture();
  604 + }
  605 +
  606 + final AnimationController controller;
  607 + final NavigatorState navigator;
  608 +
  609 + /// The drag gesture has changed by [fractionalDelta]. The total range of the
  610 + /// drag should be 0.0 to 1.0.
  611 + void dragUpdate(double delta) {
  612 + controller.value -= delta;
  613 + }
  614 +
  615 + /// The drag gesture has ended with a horizontal motion of
  616 + /// [fractionalVelocity] as a fraction of screen width per second.
  617 + void dragEnd(double velocity) {
  618 + // Fling in the appropriate direction.
  619 + // AnimationController.fling is guaranteed to
  620 + // take at least one frame.
  621 + //
  622 + // This curve has been determined through rigorously eyeballing native iOS
  623 + // animations.
  624 + const Curve animationCurve = Curves.fastLinearToSlowEaseIn;
  625 + bool animateForward;
  626 +
  627 + // If the user releases the page before mid screen with sufficient velocity,
  628 + // or after mid screen, we should animate the page out. Otherwise, the page
  629 + // should be animated back in.
  630 + if (velocity.abs() >= _kMinFlingVelocity)
  631 + animateForward = velocity <= 0;
  632 + else
  633 + animateForward = controller.value > 0.5;
  634 +
  635 + if (animateForward) {
  636 + // The closer the panel is to dismissing, the shorter the animation is.
  637 + // We want to cap the animation time, but we want to use a linear curve
  638 + // to determine it.
  639 + final int droppedPageForwardAnimationTime = min(
  640 + lerpDouble(
  641 + _kMaxDroppedSwipePageForwardAnimationTime, 0, controller.value)
  642 + .floor(),
  643 + _kMaxPageBackAnimationTime,
  644 + );
  645 + controller.animateTo(1.0,
  646 + duration: Duration(milliseconds: droppedPageForwardAnimationTime),
  647 + curve: animationCurve);
  648 + } else {
  649 + // This route is destined to pop at this point. Reuse navigator's pop.
  650 + navigator.pop();
  651 +
  652 + // The popping may have finished inline if already at the target destination.
  653 + if (controller.isAnimating) {
  654 + // Otherwise, use a custom popping animation duration and curve.
  655 + final int droppedPageBackAnimationTime = lerpDouble(
  656 + 0, _kMaxDroppedSwipePageForwardAnimationTime, controller.value)
  657 + .floor();
  658 + controller.animateBack(0.0,
  659 + duration: Duration(milliseconds: droppedPageBackAnimationTime),
  660 + curve: animationCurve);
  661 + }
  662 + }
  663 +
  664 + if (controller.isAnimating) {
  665 + // Keep the userGestureInProgress in true state so we don't change the
  666 + // curve of the page transition mid-flight since CupertinoPageTransition
  667 + // depends on userGestureInProgress.
  668 + AnimationStatusListener animationStatusCallback;
  669 + animationStatusCallback = (AnimationStatus status) {
  670 + navigator.didStopUserGesture();
  671 + controller.removeStatusListener(animationStatusCallback);
  672 + };
  673 + controller.addStatusListener(animationStatusCallback);
  674 + } else {
  675 + navigator.didStopUserGesture();
  676 + }
  677 + }
43 } 678 }
1 -import 'dart:math';  
2 -import 'dart:ui' show lerpDouble;  
3 -  
4 -import 'package:flutter/cupertino.dart';  
5 -import 'package:flutter/foundation.dart';  
6 -import 'package:flutter/gestures.dart';  
7 -  
8 -import 'transitions_type.dart';  
9 -  
10 -const double _kBackGestureWidth = 20.0;  
11 -const double _kMinFlingVelocity = 1.0;  
12 -const int _kMaxDroppedSwipePageForwardAnimationTime = 800; // Milliseconds.  
13 -  
14 -// The maximum time for a page to get reset to it's original position if the  
15 -// user releases a page mid swipe.  
16 -const int _kMaxPageBackAnimationTime = 300;  
17 -  
18 -class GetCupertino<T> extends PageRoute<T> {  
19 - /// Creates a page route for use in an iOS designed app.  
20 - ///  
21 - /// The [builder], [maintainState], and [fullscreenDialog] arguments must not  
22 - /// be null.  
23 - GetCupertino({  
24 - @required this.page,  
25 - this.title,  
26 - RouteSettings settings,  
27 - this.maintainState = true,  
28 - this.curve = Curves.linear,  
29 - this.alignment,  
30 - this.opaque = false,  
31 - this.transition = Transition.cupertino,  
32 - this.duration = const Duration(milliseconds: 400),  
33 - bool fullscreenDialog = false,  
34 - }) : assert(page != null),  
35 - assert(maintainState != null),  
36 - assert(fullscreenDialog != null),  
37 - // assert(opaque),  
38 - super(settings: settings, fullscreenDialog: fullscreenDialog);  
39 -  
40 - /// Builds the primary contents of the route.  
41 - final Widget page;  
42 -  
43 - final Duration duration;  
44 -  
45 - final String title;  
46 -  
47 - final Transition transition;  
48 -  
49 - final Curve curve;  
50 -  
51 - final Alignment alignment;  
52 -  
53 - ValueNotifier<String> _previousTitle;  
54 -  
55 - /// The title string of the previous [GetCupertino].  
56 - ///  
57 - /// The [ValueListenable]'s value is readable after the route is installed  
58 - /// onto a [Navigator]. The [ValueListenable] will also notify its listeners  
59 - /// if the value changes (such as by replacing the previous route).  
60 - ///  
61 - /// The [ValueListenable] itself will be null before the route is installed.  
62 - /// Its content value will be null if the previous route has no title or  
63 - /// is not a [GetCupertino].  
64 - ///  
65 - /// See also:  
66 - ///  
67 - /// * [ValueListenableBuilder], which can be used to listen and rebuild  
68 - /// widgets based on a ValueListenable.  
69 - ValueListenable<String> get previousTitle {  
70 - assert(  
71 - _previousTitle != null,  
72 - 'Cannot read the previousTitle for a route that has not yet been installed',  
73 - );  
74 - return _previousTitle;  
75 - }  
76 -  
77 - @override  
78 - void didChangePrevious(Route<dynamic> previousRoute) {  
79 - final String previousTitleString =  
80 - previousRoute is GetCupertino ? previousRoute.title : null;  
81 - if (_previousTitle == null) {  
82 - _previousTitle = ValueNotifier<String>(previousTitleString);  
83 - } else {  
84 - _previousTitle.value = previousTitleString;  
85 - }  
86 - super.didChangePrevious(previousRoute);  
87 - }  
88 -  
89 - @override  
90 - final bool maintainState;  
91 -  
92 - /// Allows you to set opaque to false to prevent route reconstruction.  
93 - @override  
94 - final bool opaque;  
95 -  
96 - @override  
97 - // A relatively rigorous eyeball estimation.  
98 - Duration get transitionDuration => const Duration(milliseconds: 400);  
99 -  
100 - @override  
101 - Color get barrierColor => null;  
102 -  
103 - @override  
104 - String get barrierLabel => null;  
105 -  
106 - @override  
107 - bool canTransitionTo(TransitionRoute<dynamic> nextRoute) {  
108 - // Don't perform outgoing animation if the next route is a fullscreen dialog.  
109 - return nextRoute is GetCupertino && !nextRoute.fullscreenDialog;  
110 - }  
111 -  
112 - /// True if an iOS-style back swipe pop gesture is currently underway for [route].  
113 - ///  
114 - /// This just check the route's [NavigatorState.userGestureInProgress].  
115 - ///  
116 - /// See also:  
117 - ///  
118 - /// * [popGestureEnabled], which returns true if a user-triggered pop gesture  
119 - /// would be allowed.  
120 - static bool isPopGestureInProgress(PageRoute<dynamic> route) {  
121 - return route.navigator.userGestureInProgress;  
122 - }  
123 -  
124 - /// True if an iOS-style back swipe pop gesture is currently underway for this route.  
125 - ///  
126 - /// See also:  
127 - ///  
128 - /// * [isPopGestureInProgress], which returns true if a Cupertino pop gesture  
129 - /// is currently underway for specific route.  
130 - /// * [popGestureEnabled], which returns true if a user-triggered pop gesture  
131 - /// would be allowed.  
132 - bool get popGestureInProgress => isPopGestureInProgress(this);  
133 -  
134 - /// Whether a pop gesture can be started by the user.  
135 - ///  
136 - /// Returns true if the user can edge-swipe to a previous route.  
137 - ///  
138 - /// Returns false once [isPopGestureInProgress] is true, but  
139 - /// [isPopGestureInProgress] can only become true if [popGestureEnabled] was  
140 - /// true first.  
141 - ///  
142 - /// This should only be used between frames, not during build.  
143 - bool get popGestureEnabled => _isPopGestureEnabled(this);  
144 -  
145 - static bool _isPopGestureEnabled<T>(PageRoute<T> route) {  
146 - // If there's nothing to go back to, then obviously we don't support  
147 - // the back gesture.  
148 - if (route.isFirst) return false;  
149 - // If the route wouldn't actually pop if we popped it, then the gesture  
150 - // would be really confusing (or would skip internal routes), so disallow it.  
151 - if (route.willHandlePopInternally) return false;  
152 - // If attempts to dismiss this route might be vetoed such as in a page  
153 - // with forms, then do not allow the user to dismiss the route with a swipe.  
154 - if (route.hasScopedWillPopCallback) return false;  
155 - // Fullscreen dialogs aren't dismissible by back swipe.  
156 - if (route.fullscreenDialog) return false;  
157 - // If we're in an animation already, we cannot be manually swiped.  
158 - if (route.animation.status != AnimationStatus.completed) return false;  
159 - // If we're being popped into, we also cannot be swiped until the pop above  
160 - // it completes. This translates to our secondary animation being  
161 - // dismissed.  
162 - if (route.secondaryAnimation.status != AnimationStatus.dismissed)  
163 - return false;  
164 - // If we're in a gesture already, we cannot start another.  
165 - if (isPopGestureInProgress(route)) return false;  
166 -  
167 - // Looks like a back gesture would be welcome!  
168 - return true;  
169 - }  
170 -  
171 - @override  
172 - Widget buildPage(BuildContext context, Animation<double> animation,  
173 - Animation<double> secondaryAnimation) {  
174 - final Widget child = page;  
175 - final Widget result = Semantics(  
176 - scopesRoute: true,  
177 - explicitChildNodes: true,  
178 - child: child,  
179 - );  
180 - assert(() {  
181 - if (child == null) {  
182 - throw FlutterError.fromParts(<DiagnosticsNode>[  
183 - ErrorSummary(  
184 - 'The builder for route "${settings.name}" returned null.'),  
185 - ErrorDescription('Route builders must never return null.'),  
186 - ]);  
187 - }  
188 - return true;  
189 - }());  
190 - return result;  
191 - }  
192 -  
193 - // Called by _CupertinoBackGestureDetector when a pop ("back") drag start  
194 - // gesture is detected. The returned controller handles all of the subsequent  
195 - // drag events.  
196 - static _CupertinoBackGestureController<T> _startPopGesture<T>(  
197 - PageRoute<T> route) {  
198 - assert(_isPopGestureEnabled(route));  
199 -  
200 - return _CupertinoBackGestureController<T>(  
201 - navigator: route.navigator,  
202 - controller: route.controller, // protected access  
203 - );  
204 - }  
205 -  
206 - /// Returns a [CupertinoFullscreenDialogTransition] if [route] is a full  
207 - /// screen dialog, otherwise a [CupertinoPageTransition] is returned.  
208 - ///  
209 - /// Used by [GetCupertino.buildTransitions].  
210 - ///  
211 - /// This method can be applied to any [PageRoute], not just  
212 - /// [GetCupertino]. It's typically used to provide a Cupertino style  
213 - /// horizontal transition for material widgets when the target platform  
214 - /// is [TargetPlatform.iOS].  
215 - ///  
216 - /// See also:  
217 - ///  
218 - /// * [CupertinoPageTransitionsBuilder], which uses this method to define a  
219 - /// [PageTransitionsBuilder] for the [PageTransitionsTheme].  
220 - static Widget buildPageTransitions<T>(  
221 - PageRoute<T> route,  
222 - BuildContext context,  
223 - Animation<double> animation,  
224 - Animation<double> secondaryAnimation,  
225 - Widget child,  
226 - Transition transition,  
227 - Curve curve,  
228 - Alignment alignment,  
229 - ) {  
230 - if (route.fullscreenDialog) {  
231 - return CupertinoFullscreenDialogTransition(  
232 - animation: animation,  
233 - child: child,  
234 - );  
235 - } else {  
236 - switch (transition) {  
237 - case Transition.fade:  
238 - return FadeTransition(  
239 - opacity: animation,  
240 - child: _CupertinoBackGestureDetector<T>(  
241 - enabledCallback: () => _isPopGestureEnabled<T>(route),  
242 - onStartPopGesture: () => _startPopGesture<T>(route),  
243 - child: child,  
244 - ),  
245 - );  
246 - break;  
247 - case Transition.rightToLeft:  
248 - return SlideTransition(  
249 - transformHitTests: false,  
250 - position: new Tween<Offset>(  
251 - begin: const Offset(1.0, 0.0),  
252 - end: Offset.zero,  
253 - ).animate(animation),  
254 - child: new SlideTransition(  
255 - position: new Tween<Offset>(  
256 - begin: Offset.zero,  
257 - end: const Offset(-1.0, 0.0),  
258 - ).animate(secondaryAnimation),  
259 - child: _CupertinoBackGestureDetector<T>(  
260 - enabledCallback: () => _isPopGestureEnabled<T>(route),  
261 - onStartPopGesture: () => _startPopGesture<T>(route),  
262 - child: child,  
263 - ),  
264 - ),  
265 - );  
266 - break;  
267 - case Transition.leftToRight:  
268 - return SlideTransition(  
269 - transformHitTests: false,  
270 - position: Tween<Offset>(  
271 - begin: const Offset(-1.0, 0.0),  
272 - end: Offset.zero,  
273 - ).animate(animation),  
274 - child: new SlideTransition(  
275 - position: new Tween<Offset>(  
276 - begin: Offset.zero,  
277 - end: const Offset(1.0, 0.0),  
278 - ).animate(secondaryAnimation),  
279 - child: _CupertinoBackGestureDetector<T>(  
280 - enabledCallback: () => _isPopGestureEnabled<T>(route),  
281 - onStartPopGesture: () => _startPopGesture<T>(route),  
282 - child: child,  
283 - ),  
284 - ),  
285 - );  
286 - break;  
287 - case Transition.upToDown:  
288 - return SlideTransition(  
289 - transformHitTests: false,  
290 - position: Tween<Offset>(  
291 - begin: const Offset(0.0, -1.0),  
292 - end: Offset.zero,  
293 - ).animate(animation),  
294 - child: new SlideTransition(  
295 - position: new Tween<Offset>(  
296 - begin: Offset.zero,  
297 - end: const Offset(0.0, 1.0),  
298 - ).animate(secondaryAnimation),  
299 - child: _CupertinoBackGestureDetector<T>(  
300 - enabledCallback: () => _isPopGestureEnabled<T>(route),  
301 - onStartPopGesture: () => _startPopGesture<T>(route),  
302 - child: child,  
303 - ),  
304 - ),  
305 - );  
306 - break;  
307 - case Transition.downToUp:  
308 - return SlideTransition(  
309 - transformHitTests: false,  
310 - position: Tween<Offset>(  
311 - begin: const Offset(0.0, 1.0),  
312 - end: Offset.zero,  
313 - ).animate(animation),  
314 - child: new SlideTransition(  
315 - position: new Tween<Offset>(  
316 - begin: Offset.zero,  
317 - end: const Offset(0.0, -1.0),  
318 - ).animate(secondaryAnimation),  
319 - child: _CupertinoBackGestureDetector<T>(  
320 - enabledCallback: () => _isPopGestureEnabled<T>(route),  
321 - onStartPopGesture: () => _startPopGesture<T>(route),  
322 - child: child,  
323 - ),  
324 - ),  
325 - );  
326 - break;  
327 - case Transition.scale:  
328 - return ScaleTransition(  
329 - alignment: alignment,  
330 - scale: CurvedAnimation(  
331 - parent: animation,  
332 - curve: Interval(  
333 - 0.00,  
334 - 0.50,  
335 - curve: curve,  
336 - ),  
337 - ),  
338 - child: _CupertinoBackGestureDetector<T>(  
339 - enabledCallback: () => _isPopGestureEnabled<T>(route),  
340 - onStartPopGesture: () => _startPopGesture<T>(route),  
341 - child: child,  
342 - ),  
343 - );  
344 - break;  
345 - case Transition.rotate:  
346 - return RotationTransition(  
347 - alignment: alignment,  
348 - turns: animation,  
349 - child: ScaleTransition(  
350 - alignment: alignment,  
351 - scale: animation,  
352 - child: FadeTransition(  
353 - opacity: animation,  
354 - child: _CupertinoBackGestureDetector<T>(  
355 - enabledCallback: () => _isPopGestureEnabled<T>(route),  
356 - onStartPopGesture: () => _startPopGesture<T>(route),  
357 - child: child,  
358 - ),  
359 - ),  
360 - ),  
361 - );  
362 - break;  
363 - case Transition.size:  
364 - return Align(  
365 - alignment: alignment,  
366 - child: SizeTransition(  
367 - sizeFactor: CurvedAnimation(  
368 - parent: animation,  
369 - curve: curve,  
370 - ),  
371 - child: _CupertinoBackGestureDetector<T>(  
372 - enabledCallback: () => _isPopGestureEnabled<T>(route),  
373 - onStartPopGesture: () => _startPopGesture<T>(route),  
374 - child: child,  
375 - ),  
376 - ),  
377 - );  
378 - break;  
379 - case Transition.rightToLeftWithFade:  
380 - return SlideTransition(  
381 - position: Tween<Offset>(  
382 - begin: const Offset(1.0, 0.0),  
383 - end: Offset.zero,  
384 - ).animate(animation),  
385 - child: FadeTransition(  
386 - opacity: animation,  
387 - child: SlideTransition(  
388 - position: Tween<Offset>(  
389 - begin: Offset.zero,  
390 - end: const Offset(-1.0, 0.0),  
391 - ).animate(secondaryAnimation),  
392 - child: _CupertinoBackGestureDetector<T>(  
393 - enabledCallback: () => _isPopGestureEnabled<T>(route),  
394 - onStartPopGesture: () => _startPopGesture<T>(route),  
395 - child: child,  
396 - ),  
397 - ),  
398 - ),  
399 - );  
400 - break;  
401 - case Transition.leftToRightWithFade:  
402 - return SlideTransition(  
403 - position: Tween<Offset>(  
404 - begin: const Offset(-1.0, 0.0),  
405 - end: Offset.zero,  
406 - ).animate(animation),  
407 - child: FadeTransition(  
408 - opacity: animation,  
409 - child: SlideTransition(  
410 - position: Tween<Offset>(  
411 - begin: Offset.zero,  
412 - end: const Offset(1.0, 0.0),  
413 - ).animate(secondaryAnimation),  
414 - child: _CupertinoBackGestureDetector<T>(  
415 - enabledCallback: () => _isPopGestureEnabled<T>(route),  
416 - onStartPopGesture: () => _startPopGesture<T>(route),  
417 - child: child,  
418 - ),  
419 - ),  
420 - ),  
421 - );  
422 - break;  
423 - case Transition.cupertino:  
424 - return CupertinoPageTransition(  
425 - primaryRouteAnimation: animation,  
426 - secondaryRouteAnimation: secondaryAnimation,  
427 - // Check if the route has an animation that's currently participating  
428 - // in a back swipe gesture.  
429 - //  
430 - // In the middle of a back gesture drag, let the transition be linear to  
431 - // match finger motions.  
432 - linearTransition: isPopGestureInProgress(route),  
433 - child: _CupertinoBackGestureDetector<T>(  
434 - enabledCallback: () => _isPopGestureEnabled<T>(route),  
435 - onStartPopGesture: () => _startPopGesture<T>(route),  
436 - child: child,  
437 - ),  
438 - );  
439 - break;  
440 - default:  
441 - return CupertinoPageTransition(  
442 - primaryRouteAnimation: animation,  
443 - secondaryRouteAnimation: secondaryAnimation,  
444 - // Check if the route has an animation that's currently participating  
445 - // in a back swipe gesture.  
446 - //  
447 - // In the middle of a back gesture drag, let the transition be linear to  
448 - // match finger motions.  
449 - linearTransition: isPopGestureInProgress(route),  
450 - child: _CupertinoBackGestureDetector<T>(  
451 - enabledCallback: () => _isPopGestureEnabled<T>(route),  
452 - onStartPopGesture: () => _startPopGesture<T>(route),  
453 - child: child,  
454 - ),  
455 - );  
456 - }  
457 - }  
458 - }  
459 -  
460 - @override  
461 - Widget buildTransitions(BuildContext context, Animation<double> animation,  
462 - Animation<double> secondaryAnimation, Widget child) {  
463 - return buildPageTransitions<T>(this, context, animation, secondaryAnimation,  
464 - child, transition, curve, alignment);  
465 - }  
466 -  
467 - @override  
468 - String get debugLabel => '${super.debugLabel}(${settings.name})';  
469 -}  
470 -  
471 -class _CupertinoBackGestureDetector<T> extends StatefulWidget {  
472 - const _CupertinoBackGestureDetector({  
473 - Key key,  
474 - @required this.enabledCallback,  
475 - @required this.onStartPopGesture,  
476 - @required this.child,  
477 - }) : assert(enabledCallback != null),  
478 - assert(onStartPopGesture != null),  
479 - assert(child != null),  
480 - super(key: key);  
481 -  
482 - final Widget child;  
483 -  
484 - final ValueGetter<bool> enabledCallback;  
485 -  
486 - final ValueGetter<_CupertinoBackGestureController<T>> onStartPopGesture;  
487 -  
488 - @override  
489 - _CupertinoBackGestureDetectorState<T> createState() =>  
490 - _CupertinoBackGestureDetectorState<T>();  
491 -}  
492 -  
493 -class _CupertinoBackGestureDetectorState<T>  
494 - extends State<_CupertinoBackGestureDetector<T>> {  
495 - _CupertinoBackGestureController<T> _backGestureController;  
496 -  
497 - HorizontalDragGestureRecognizer _recognizer;  
498 -  
499 - @override  
500 - void initState() {  
501 - super.initState();  
502 - _recognizer = HorizontalDragGestureRecognizer(debugOwner: this)  
503 - ..onStart = _handleDragStart  
504 - ..onUpdate = _handleDragUpdate  
505 - ..onEnd = _handleDragEnd  
506 - ..onCancel = _handleDragCancel;  
507 - }  
508 -  
509 - @override  
510 - void dispose() {  
511 - _recognizer.dispose();  
512 - super.dispose();  
513 - }  
514 -  
515 - void _handleDragStart(DragStartDetails details) {  
516 - assert(mounted);  
517 - assert(_backGestureController == null);  
518 - _backGestureController = widget.onStartPopGesture();  
519 - }  
520 -  
521 - void _handleDragUpdate(DragUpdateDetails details) {  
522 - assert(mounted);  
523 - assert(_backGestureController != null);  
524 - _backGestureController.dragUpdate(  
525 - _convertToLogical(details.primaryDelta / context.size.width));  
526 - }  
527 -  
528 - void _handleDragEnd(DragEndDetails details) {  
529 - assert(mounted);  
530 - assert(_backGestureController != null);  
531 - _backGestureController.dragEnd(_convertToLogical(  
532 - details.velocity.pixelsPerSecond.dx / context.size.width));  
533 - _backGestureController = null;  
534 - }  
535 -  
536 - void _handleDragCancel() {  
537 - assert(mounted);  
538 - // This can be called even if start is not called, paired with the "down" event  
539 - // that we don't consider here.  
540 - _backGestureController?.dragEnd(0.0);  
541 - _backGestureController = null;  
542 - }  
543 -  
544 - void _handlePointerDown(PointerDownEvent event) {  
545 - if (widget.enabledCallback()) _recognizer.addPointer(event);  
546 - }  
547 -  
548 - double _convertToLogical(double value) {  
549 - switch (Directionality.of(context)) {  
550 - case TextDirection.rtl:  
551 - return -value;  
552 - case TextDirection.ltr:  
553 - return value;  
554 - }  
555 - return null;  
556 - }  
557 -  
558 - @override  
559 - Widget build(BuildContext context) {  
560 - assert(debugCheckHasDirectionality(context));  
561 - // For devices with notches, the drag area needs to be larger on the side  
562 - // that has the notch.  
563 - double dragAreaWidth = Directionality.of(context) == TextDirection.ltr  
564 - ? MediaQuery.of(context).padding.left  
565 - : MediaQuery.of(context).padding.right;  
566 - dragAreaWidth = max(dragAreaWidth, _kBackGestureWidth);  
567 - return Stack(  
568 - fit: StackFit.passthrough,  
569 - children: <Widget>[  
570 - widget.child,  
571 - PositionedDirectional(  
572 - start: 0.0,  
573 - width: dragAreaWidth,  
574 - top: 0.0,  
575 - bottom: 0.0,  
576 - child: Listener(  
577 - onPointerDown: _handlePointerDown,  
578 - behavior: HitTestBehavior.translucent,  
579 - ),  
580 - ),  
581 - ],  
582 - );  
583 - }  
584 -}  
585 -  
586 -class _CupertinoBackGestureController<T> {  
587 - /// Creates a controller for an iOS-style back gesture.  
588 - ///  
589 - /// The [navigator] and [controller] arguments must not be null.  
590 - _CupertinoBackGestureController({  
591 - @required this.navigator,  
592 - @required this.controller,  
593 - }) : assert(navigator != null),  
594 - assert(controller != null) {  
595 - navigator.didStartUserGesture();  
596 - }  
597 -  
598 - final AnimationController controller;  
599 - final NavigatorState navigator;  
600 -  
601 - /// The drag gesture has changed by [fractionalDelta]. The total range of the  
602 - /// drag should be 0.0 to 1.0.  
603 - void dragUpdate(double delta) {  
604 - controller.value -= delta;  
605 - }  
606 -  
607 - /// The drag gesture has ended with a horizontal motion of  
608 - /// [fractionalVelocity] as a fraction of screen width per second.  
609 - void dragEnd(double velocity) {  
610 - // Fling in the appropriate direction.  
611 - // AnimationController.fling is guaranteed to  
612 - // take at least one frame.  
613 - //  
614 - // This curve has been determined through rigorously eyeballing native iOS  
615 - // animations.  
616 - const Curve animationCurve = Curves.fastLinearToSlowEaseIn;  
617 - bool animateForward;  
618 -  
619 - // If the user releases the page before mid screen with sufficient velocity,  
620 - // or after mid screen, we should animate the page out. Otherwise, the page  
621 - // should be animated back in.  
622 - if (velocity.abs() >= _kMinFlingVelocity)  
623 - animateForward = velocity <= 0;  
624 - else  
625 - animateForward = controller.value > 0.5;  
626 -  
627 - if (animateForward) {  
628 - // The closer the panel is to dismissing, the shorter the animation is.  
629 - // We want to cap the animation time, but we want to use a linear curve  
630 - // to determine it.  
631 - final int droppedPageForwardAnimationTime = min(  
632 - lerpDouble(  
633 - _kMaxDroppedSwipePageForwardAnimationTime, 0, controller.value)  
634 - .floor(),  
635 - _kMaxPageBackAnimationTime,  
636 - );  
637 - controller.animateTo(1.0,  
638 - duration: Duration(milliseconds: droppedPageForwardAnimationTime),  
639 - curve: animationCurve);  
640 - } else {  
641 - // This route is destined to pop at this point. Reuse navigator's pop.  
642 - navigator.pop();  
643 -  
644 - // The popping may have finished inline if already at the target destination.  
645 - if (controller.isAnimating) {  
646 - // Otherwise, use a custom popping animation duration and curve.  
647 - final int droppedPageBackAnimationTime = lerpDouble(  
648 - 0, _kMaxDroppedSwipePageForwardAnimationTime, controller.value)  
649 - .floor();  
650 - controller.animateBack(0.0,  
651 - duration: Duration(milliseconds: droppedPageBackAnimationTime),  
652 - curve: animationCurve);  
653 - }  
654 - }  
655 -  
656 - if (controller.isAnimating) {  
657 - // Keep the userGestureInProgress in true state so we don't change the  
658 - // curve of the page transition mid-flight since CupertinoPageTransition  
659 - // depends on userGestureInProgress.  
660 - AnimationStatusListener animationStatusCallback;  
661 - animationStatusCallback = (AnimationStatus status) {  
662 - navigator.didStopUserGesture();  
663 - controller.removeStatusListener(animationStatusCallback);  
664 - };  
665 - controller.addStatusListener(animationStatusCallback);  
666 - } else {  
667 - navigator.didStopUserGesture();  
668 - }  
669 - }  
670 -}  
1 -import 'package:flutter/material.dart';  
2 -import 'transitions_type.dart';  
3 -  
4 -class GetMaterial<T> extends PageRouteBuilder<T> {  
5 - /// Construct a Modified PageRoute whose contents are defined by child.  
6 - /// The values of [child], [maintainState], [opaque], and [fullScreenDialog] must not  
7 - /// be null.  
8 - GetMaterial({  
9 - Key key,  
10 - RouteSettings settings,  
11 - this.opaque = false,  
12 - this.maintainState = true,  
13 - @required this.page,  
14 - this.transition = Transition.fade,  
15 - this.curve = Curves.linear,  
16 - this.alignment,  
17 - this.duration = const Duration(milliseconds: 400),  
18 - bool fullscreenDialog = false,  
19 - }) : assert(page != null),  
20 - assert(maintainState != null),  
21 - assert(fullscreenDialog != null),  
22 - assert(opaque != null),  
23 - super(  
24 - fullscreenDialog: fullscreenDialog,  
25 - pageBuilder: (BuildContext context, Animation<double> animation,  
26 - Animation<double> secondaryAnimation) {  
27 - return page;  
28 - },  
29 - transitionDuration: duration,  
30 - settings: settings,  
31 - transitionsBuilder: (BuildContext context,  
32 - Animation<double> animation,  
33 - Animation<double> secondaryAnimation,  
34 - Widget child) {  
35 - switch (transition) {  
36 - case Transition.fade:  
37 - return FadeTransition(opacity: animation, child: child);  
38 - break;  
39 - case Transition.rightToLeft:  
40 - return SlideTransition(  
41 - transformHitTests: false,  
42 - position: new Tween<Offset>(  
43 - begin: const Offset(1.0, 0.0),  
44 - end: Offset.zero,  
45 - ).animate(animation),  
46 - child: new SlideTransition(  
47 - position: new Tween<Offset>(  
48 - begin: Offset.zero,  
49 - end: const Offset(-1.0, 0.0),  
50 - ).animate(secondaryAnimation),  
51 - child: child,  
52 - ),  
53 - );  
54 - break;  
55 - case Transition.leftToRight:  
56 - return SlideTransition(  
57 - transformHitTests: false,  
58 - position: Tween<Offset>(  
59 - begin: const Offset(-1.0, 0.0),  
60 - end: Offset.zero,  
61 - ).animate(animation),  
62 - child: new SlideTransition(  
63 - position: new Tween<Offset>(  
64 - begin: Offset.zero,  
65 - end: const Offset(1.0, 0.0),  
66 - ).animate(secondaryAnimation),  
67 - child: child,  
68 - ),  
69 - );  
70 - break;  
71 - case Transition.upToDown:  
72 - return SlideTransition(  
73 - transformHitTests: false,  
74 - position: Tween<Offset>(  
75 - begin: const Offset(0.0, -1.0),  
76 - end: Offset.zero,  
77 - ).animate(animation),  
78 - child: new SlideTransition(  
79 - position: new Tween<Offset>(  
80 - begin: Offset.zero,  
81 - end: const Offset(0.0, 1.0),  
82 - ).animate(secondaryAnimation),  
83 - child: child,  
84 - ),  
85 - );  
86 - break;  
87 - case Transition.downToUp:  
88 - return SlideTransition(  
89 - transformHitTests: false,  
90 - position: Tween<Offset>(  
91 - begin: const Offset(0.0, 1.0),  
92 - end: Offset.zero,  
93 - ).animate(animation),  
94 - child: new SlideTransition(  
95 - position: new Tween<Offset>(  
96 - begin: Offset.zero,  
97 - end: const Offset(0.0, -1.0),  
98 - ).animate(secondaryAnimation),  
99 - child: child,  
100 - ),  
101 - );  
102 - break;  
103 - case Transition.scale:  
104 - return ScaleTransition(  
105 - alignment: alignment,  
106 - scale: CurvedAnimation(  
107 - parent: animation,  
108 - curve: Interval(  
109 - 0.00,  
110 - 0.50,  
111 - curve: curve,  
112 - ),  
113 - ),  
114 - child: child,  
115 - );  
116 - break;  
117 - case Transition.rotate:  
118 - return RotationTransition(  
119 - alignment: alignment,  
120 - turns: animation,  
121 - child: ScaleTransition(  
122 - alignment: alignment,  
123 - scale: animation,  
124 - child: FadeTransition(  
125 - opacity: animation,  
126 - child: child,  
127 - ),  
128 - ),  
129 - );  
130 - break;  
131 - case Transition.size:  
132 - return Align(  
133 - alignment: alignment,  
134 - child: SizeTransition(  
135 - sizeFactor: CurvedAnimation(  
136 - parent: animation,  
137 - curve: curve,  
138 - ),  
139 - child: child,  
140 - ),  
141 - );  
142 - break;  
143 - case Transition.rightToLeftWithFade:  
144 - return SlideTransition(  
145 - position: Tween<Offset>(  
146 - begin: const Offset(1.0, 0.0),  
147 - end: Offset.zero,  
148 - ).animate(animation),  
149 - child: FadeTransition(  
150 - opacity: animation,  
151 - child: SlideTransition(  
152 - position: Tween<Offset>(  
153 - begin: Offset.zero,  
154 - end: const Offset(-1.0, 0.0),  
155 - ).animate(secondaryAnimation),  
156 - child: child,  
157 - ),  
158 - ),  
159 - );  
160 - break;  
161 - case Transition.leftToRightWithFade:  
162 - return SlideTransition(  
163 - position: Tween<Offset>(  
164 - begin: const Offset(-1.0, 0.0),  
165 - end: Offset.zero,  
166 - ).animate(animation),  
167 - child: FadeTransition(  
168 - opacity: animation,  
169 - child: SlideTransition(  
170 - position: Tween<Offset>(  
171 - begin: Offset.zero,  
172 - end: const Offset(1.0, 0.0),  
173 - ).animate(secondaryAnimation),  
174 - child: child,  
175 - ),  
176 - ),  
177 - );  
178 - break;  
179 - default:  
180 - return FadeTransition(opacity: animation, child: child);  
181 - }  
182 - });  
183 -  
184 - @override  
185 - final bool maintainState;  
186 -  
187 - /// Allows you to set opaque to false to prevent route reconstruction.  
188 - @override  
189 - final bool opaque;  
190 -  
191 - @override  
192 - Duration get transitionDuration => const Duration(milliseconds: 300);  
193 -  
194 - @override  
195 - Color get barrierColor => null;  
196 -  
197 - @override  
198 - String get barrierLabel => null;  
199 -  
200 - // @override  
201 - // bool canTransitionFrom(TransitionRoute<dynamic> previousRoute) {  
202 - // return previousRoute is GetMaterial || previousRoute is CupertinoPageRoute;  
203 - // }  
204 -  
205 - // @override  
206 - // bool canTransitionTo(TransitionRoute<dynamic> nextRoute) {  
207 - // // Don't perform outgoing animation if the next route is a fullscreen dialog.  
208 - // return (nextRoute is GetMaterial && !nextRoute.fullscreenDialog) ||  
209 - // (nextRoute is CupertinoPageRoute && !nextRoute.fullscreenDialog);  
210 - // }  
211 -  
212 - @override  
213 - String get debugLabel => '${super.debugLabel}(${settings.name})';  
214 -  
215 - final Widget page;  
216 -  
217 - final Transition transition;  
218 -  
219 - final Curve curve;  
220 -  
221 - final Alignment alignment;  
222 -  
223 - final Duration duration;  
224 -}  
@@ -7,42 +7,42 @@ packages: @@ -7,42 +7,42 @@ packages:
7 name: archive 7 name: archive
8 url: "https://pub.dartlang.org" 8 url: "https://pub.dartlang.org"
9 source: hosted 9 source: hosted
10 - version: "2.0.11" 10 + version: "2.0.13"
11 args: 11 args:
12 dependency: transitive 12 dependency: transitive
13 description: 13 description:
14 name: args 14 name: args
15 url: "https://pub.dartlang.org" 15 url: "https://pub.dartlang.org"
16 source: hosted 16 source: hosted
17 - version: "1.5.2" 17 + version: "1.6.0"
18 async: 18 async:
19 dependency: transitive 19 dependency: transitive
20 description: 20 description:
21 name: async 21 name: async
22 url: "https://pub.dartlang.org" 22 url: "https://pub.dartlang.org"
23 source: hosted 23 source: hosted
24 - version: "2.4.0" 24 + version: "2.4.1"
25 boolean_selector: 25 boolean_selector:
26 dependency: transitive 26 dependency: transitive
27 description: 27 description:
28 name: boolean_selector 28 name: boolean_selector
29 url: "https://pub.dartlang.org" 29 url: "https://pub.dartlang.org"
30 source: hosted 30 source: hosted
31 - version: "1.0.5" 31 + version: "2.0.0"
32 charcode: 32 charcode:
33 dependency: transitive 33 dependency: transitive
34 description: 34 description:
35 name: charcode 35 name: charcode
36 url: "https://pub.dartlang.org" 36 url: "https://pub.dartlang.org"
37 source: hosted 37 source: hosted
38 - version: "1.1.2" 38 + version: "1.1.3"
39 collection: 39 collection:
40 dependency: transitive 40 dependency: transitive
41 description: 41 description:
42 name: collection 42 name: collection
43 url: "https://pub.dartlang.org" 43 url: "https://pub.dartlang.org"
44 source: hosted 44 source: hosted
45 - version: "1.14.11" 45 + version: "1.14.12"
46 convert: 46 convert:
47 dependency: transitive 47 dependency: transitive
48 description: 48 description:
@@ -56,7 +56,7 @@ packages: @@ -56,7 +56,7 @@ packages:
56 name: crypto 56 name: crypto
57 url: "https://pub.dartlang.org" 57 url: "https://pub.dartlang.org"
58 source: hosted 58 source: hosted
59 - version: "2.1.3" 59 + version: "2.1.4"
60 flutter: 60 flutter:
61 dependency: "direct main" 61 dependency: "direct main"
62 description: flutter 62 description: flutter
@@ -73,7 +73,7 @@ packages: @@ -73,7 +73,7 @@ packages:
73 name: image 73 name: image
74 url: "https://pub.dartlang.org" 74 url: "https://pub.dartlang.org"
75 source: hosted 75 source: hosted
76 - version: "2.1.4" 76 + version: "2.1.12"
77 matcher: 77 matcher:
78 dependency: transitive 78 dependency: transitive
79 description: 79 description:
@@ -108,7 +108,7 @@ packages: @@ -108,7 +108,7 @@ packages:
108 name: quiver 108 name: quiver
109 url: "https://pub.dartlang.org" 109 url: "https://pub.dartlang.org"
110 source: hosted 110 source: hosted
111 - version: "2.0.5" 111 + version: "2.1.3"
112 sky_engine: 112 sky_engine:
113 dependency: transitive 113 dependency: transitive
114 description: flutter 114 description: flutter
@@ -120,7 +120,7 @@ packages: @@ -120,7 +120,7 @@ packages:
120 name: source_span 120 name: source_span
121 url: "https://pub.dartlang.org" 121 url: "https://pub.dartlang.org"
122 source: hosted 122 source: hosted
123 - version: "1.5.5" 123 + version: "1.7.0"
124 stack_trace: 124 stack_trace:
125 dependency: transitive 125 dependency: transitive
126 description: 126 description:
@@ -176,6 +176,6 @@ packages: @@ -176,6 +176,6 @@ packages:
176 name: xml 176 name: xml
177 url: "https://pub.dartlang.org" 177 url: "https://pub.dartlang.org"
178 source: hosted 178 source: hosted
179 - version: "3.5.0" 179 + version: "3.6.1"
180 sdks: 180 sdks:
181 - dart: ">=2.4.0 <3.0.0" 181 + dart: ">=2.6.0 <3.0.0"
1 name: get 1 name: get
2 description: Navigate between screens, display snackbars, dialogs and bottomSheets, from anywhere in your code without context with Get. 2 description: Navigate between screens, display snackbars, dialogs and bottomSheets, from anywhere in your code without context with Get.
3 -version: 1.13.1-dev 3 +version: 1.14.0-dev
4 homepage: https://github.com/jonataslaw/get 4 homepage: https://github.com/jonataslaw/get
5 5
6 environment: 6 environment: