Showing
11 changed files
with
763 additions
and
997 deletions
@@ -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: |
-
Please register or login to post a comment