Committed by
GitHub
feat: bring up to date (#391)
* fix: lints * feat: fix inner not resizing * fix: expanded
Showing
60 changed files
with
561 additions
and
323 deletions
@@ -15,8 +15,8 @@ EXTERNAL SOURCES: | @@ -15,8 +15,8 @@ EXTERNAL SOURCES: | ||
15 | 15 | ||
16 | SPEC CHECKSUMS: | 16 | SPEC CHECKSUMS: |
17 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 | 17 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 |
18 | - url_launcher_ios: ae1517e5e344f5544fb090b079e11f399dfbe4d2 | 18 | + url_launcher_ios: 68d46cc9766d0c41dbdc884310529557e3cd7a86 |
19 | 19 | ||
20 | PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 | 20 | PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 |
21 | 21 | ||
22 | -COCOAPODS: 1.13.0 | 22 | +COCOAPODS: 1.14.3 |
@@ -93,7 +93,7 @@ class CupertinoSharePage extends StatelessWidget { | @@ -93,7 +93,7 @@ class CupertinoSharePage extends StatelessWidget { | ||
93 | } | 93 | } |
94 | 94 | ||
95 | class PhotoShareBottomSheet extends StatelessWidget { | 95 | class PhotoShareBottomSheet extends StatelessWidget { |
96 | - const PhotoShareBottomSheet({Key? key}) : super(key: key); | 96 | + const PhotoShareBottomSheet({super.key}); |
97 | 97 | ||
98 | @override | 98 | @override |
99 | Widget build(BuildContext context) { | 99 | Widget build(BuildContext context) { |
@@ -539,9 +539,9 @@ final actions2 = [ | @@ -539,9 +539,9 @@ final actions2 = [ | ||
539 | ]; | 539 | ]; |
540 | 540 | ||
541 | extension ListUtils<T> on List<T> { | 541 | extension ListUtils<T> on List<T> { |
542 | - List<T> addItemInBetween<A extends T>(A item) => this.length == 0 | 542 | + List<T> addItemInBetween<A extends T>(A item) => isEmpty |
543 | ? this | 543 | ? this |
544 | - : (this.fold([], (r, element) => [...r, element, item])..removeLast()); | 544 | + : (fold([], (r, element) => [...r, element, item])..removeLast()); |
545 | } | 545 | } |
546 | 546 | ||
547 | class SimpleSliverDelegate extends SliverPersistentHeaderDelegate { | 547 | class SimpleSliverDelegate extends SliverPersistentHeaderDelegate { |
@@ -92,12 +92,12 @@ class MyApp extends StatelessWidget { | @@ -92,12 +92,12 @@ class MyApp extends StatelessWidget { | ||
92 | } | 92 | } |
93 | 93 | ||
94 | class MyHomePage extends StatefulWidget { | 94 | class MyHomePage extends StatefulWidget { |
95 | - MyHomePage({Key? key, required this.title}) : super(key: key); | 95 | + MyHomePage({super.key, required this.title}); |
96 | 96 | ||
97 | final String title; | 97 | final String title; |
98 | 98 | ||
99 | @override | 99 | @override |
100 | - _MyHomePageState createState() => _MyHomePageState(); | 100 | + State<MyHomePage> createState() => _MyHomePageState(); |
101 | } | 101 | } |
102 | 102 | ||
103 | class _MyHomePageState extends State<MyHomePage> { | 103 | class _MyHomePageState extends State<MyHomePage> { |
@@ -11,11 +11,10 @@ class AvatarBottomSheet extends StatelessWidget { | @@ -11,11 +11,10 @@ class AvatarBottomSheet extends StatelessWidget { | ||
11 | final SystemUiOverlayStyle? overlayStyle; | 11 | final SystemUiOverlayStyle? overlayStyle; |
12 | 12 | ||
13 | const AvatarBottomSheet( | 13 | const AvatarBottomSheet( |
14 | - {Key? key, | 14 | + {super.key, |
15 | required this.child, | 15 | required this.child, |
16 | required this.animation, | 16 | required this.animation, |
17 | - this.overlayStyle}) | ||
18 | - : super(key: key); | 17 | + this.overlayStyle}); |
19 | 18 | ||
20 | @override | 19 | @override |
21 | Widget build(BuildContext context) { | 20 | Widget build(BuildContext context) { |
@@ -5,8 +5,7 @@ class FloatingModal extends StatelessWidget { | @@ -5,8 +5,7 @@ class FloatingModal extends StatelessWidget { | ||
5 | final Widget child; | 5 | final Widget child; |
6 | final Color? backgroundColor; | 6 | final Color? backgroundColor; |
7 | 7 | ||
8 | - const FloatingModal({Key? key, required this.child, this.backgroundColor}) | ||
9 | - : super(key: key); | 8 | + const FloatingModal({super.key, required this.child, this.backgroundColor}); |
10 | 9 | ||
11 | @override | 10 | @override |
12 | Widget build(BuildContext context) { | 11 | Widget build(BuildContext context) { |
@@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; | @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; | ||
3 | import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; | 3 | import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; |
4 | 4 | ||
5 | class ComplexModal extends StatelessWidget { | 5 | class ComplexModal extends StatelessWidget { |
6 | - const ComplexModal({Key? key}) : super(key: key); | 6 | + const ComplexModal({super.key}); |
7 | 7 | ||
8 | @override | 8 | @override |
9 | Widget build(BuildContext context) { | 9 | Widget build(BuildContext context) { |
1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
2 | 2 | ||
3 | class ModalFit extends StatelessWidget { | 3 | class ModalFit extends StatelessWidget { |
4 | - const ModalFit({Key? key}) : super(key: key); | 4 | + const ModalFit({super.key}); |
5 | 5 | ||
6 | @override | 6 | @override |
7 | Widget build(BuildContext context) { | 7 | Widget build(BuildContext context) { |
@@ -5,7 +5,7 @@ import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; | @@ -5,7 +5,7 @@ import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; | ||
5 | class ModalInsideModal extends StatelessWidget { | 5 | class ModalInsideModal extends StatelessWidget { |
6 | final bool reverse; | 6 | final bool reverse; |
7 | 7 | ||
8 | - const ModalInsideModal({Key? key, this.reverse = false}) : super(key: key); | 8 | + const ModalInsideModal({super.key, this.reverse = false}); |
9 | 9 | ||
10 | @override | 10 | @override |
11 | Widget build(BuildContext context) { | 11 | Widget build(BuildContext context) { |
@@ -2,7 +2,7 @@ import 'package:flutter/cupertino.dart'; | @@ -2,7 +2,7 @@ import 'package:flutter/cupertino.dart'; | ||
2 | import 'package:flutter/material.dart'; | 2 | import 'package:flutter/material.dart'; |
3 | 3 | ||
4 | class SimpleModal extends StatelessWidget { | 4 | class SimpleModal extends StatelessWidget { |
5 | - const SimpleModal({Key? key}) : super(key: key); | 5 | + const SimpleModal({super.key}); |
6 | 6 | ||
7 | @override | 7 | @override |
8 | Widget build(BuildContext context) { | 8 | Widget build(BuildContext context) { |
@@ -2,7 +2,7 @@ import 'package:flutter/cupertino.dart'; | @@ -2,7 +2,7 @@ import 'package:flutter/cupertino.dart'; | ||
2 | import 'package:flutter/material.dart'; | 2 | import 'package:flutter/material.dart'; |
3 | 3 | ||
4 | class ModalWillScope extends StatelessWidget { | 4 | class ModalWillScope extends StatelessWidget { |
5 | - const ModalWillScope({Key? key}) : super(key: key); | 5 | + const ModalWillScope({super.key}); |
6 | 6 | ||
7 | @override | 7 | @override |
8 | Widget build(BuildContext context) { | 8 | Widget build(BuildContext context) { |
@@ -3,30 +3,30 @@ import 'package:flutter/material.dart'; | @@ -3,30 +3,30 @@ import 'package:flutter/material.dart'; | ||
3 | import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; | 3 | import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; |
4 | 4 | ||
5 | class ModalWithNavigator extends StatelessWidget { | 5 | class ModalWithNavigator extends StatelessWidget { |
6 | - const ModalWithNavigator({Key? key}) : super(key: key); | 6 | + const ModalWithNavigator({super.key}); |
7 | 7 | ||
8 | @override | 8 | @override |
9 | - Widget build(BuildContext rootContext) { | 9 | + Widget build(BuildContext context) { |
10 | return Material( | 10 | return Material( |
11 | child: Navigator( | 11 | child: Navigator( |
12 | onGenerateRoute: (_) => MaterialPageRoute( | 12 | onGenerateRoute: (_) => MaterialPageRoute( |
13 | - builder: (context2) => Builder( | ||
14 | - builder: (context) => CupertinoPageScaffold( | 13 | + builder: (childContext) => Builder( |
14 | + builder: (childContext2) => CupertinoPageScaffold( | ||
15 | navigationBar: CupertinoNavigationBar( | 15 | navigationBar: CupertinoNavigationBar( |
16 | leading: Container(), middle: Text('Modal Page')), | 16 | leading: Container(), middle: Text('Modal Page')), |
17 | child: SafeArea( | 17 | child: SafeArea( |
18 | bottom: false, | 18 | bottom: false, |
19 | child: ListView( | 19 | child: ListView( |
20 | shrinkWrap: true, | 20 | shrinkWrap: true, |
21 | - controller: ModalScrollController.of(context), | 21 | + controller: ModalScrollController.of(childContext2), |
22 | children: ListTile.divideTiles( | 22 | children: ListTile.divideTiles( |
23 | - context: context, | 23 | + context: childContext2, |
24 | tiles: List.generate( | 24 | tiles: List.generate( |
25 | 100, | 25 | 100, |
26 | (index) => ListTile( | 26 | (index) => ListTile( |
27 | title: Text('Item'), | 27 | title: Text('Item'), |
28 | onTap: () { | 28 | onTap: () { |
29 | - Navigator.of(context).push( | 29 | + Navigator.of(childContext2).push( |
30 | MaterialPageRoute( | 30 | MaterialPageRoute( |
31 | builder: (context) => CupertinoPageScaffold( | 31 | builder: (context) => CupertinoPageScaffold( |
32 | navigationBar: CupertinoNavigationBar( | 32 | navigationBar: CupertinoNavigationBar( |
@@ -37,7 +37,7 @@ class ModalWithNavigator extends StatelessWidget { | @@ -37,7 +37,7 @@ class ModalWithNavigator extends StatelessWidget { | ||
37 | children: <Widget>[ | 37 | children: <Widget>[ |
38 | MaterialButton( | 38 | MaterialButton( |
39 | onPressed: () => | 39 | onPressed: () => |
40 | - Navigator.of(rootContext).pop(), | 40 | + Navigator.of(context).pop(), |
41 | child: Text('touch here'), | 41 | child: Text('touch here'), |
42 | ) | 42 | ) |
43 | ], | 43 | ], |
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; | @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; | ||
2 | import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; | 2 | import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; |
3 | 3 | ||
4 | class NestedScrollModal extends StatelessWidget { | 4 | class NestedScrollModal extends StatelessWidget { |
5 | - const NestedScrollModal({Key? key}) : super(key: key); | 5 | + const NestedScrollModal({super.key}); |
6 | 6 | ||
7 | @override | 7 | @override |
8 | Widget build(BuildContext context) { | 8 | Widget build(BuildContext context) { |
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; | @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; | ||
2 | import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; | 2 | import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; |
3 | 3 | ||
4 | class ModalWithPageView extends StatelessWidget { | 4 | class ModalWithPageView extends StatelessWidget { |
5 | - const ModalWithPageView({Key? key}) : super(key: key); | 5 | + const ModalWithPageView({super.key}); |
6 | 6 | ||
7 | @override | 7 | @override |
8 | Widget build(BuildContext context) { | 8 | Widget build(BuildContext context) { |
@@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; | @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; | ||
3 | import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; | 3 | import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; |
4 | 4 | ||
5 | class ModalWithScroll extends StatelessWidget { | 5 | class ModalWithScroll extends StatelessWidget { |
6 | - const ModalWithScroll({Key? key}) : super(key: key); | 6 | + const ModalWithScroll({super.key}); |
7 | 7 | ||
8 | @override | 8 | @override |
9 | Widget build(BuildContext context) { | 9 | Widget build(BuildContext context) { |
@@ -6,7 +6,7 @@ import 'package:url_launcher/url_launcher_string.dart'; | @@ -6,7 +6,7 @@ import 'package:url_launcher/url_launcher_string.dart'; | ||
6 | class WebFrame extends StatelessWidget { | 6 | class WebFrame extends StatelessWidget { |
7 | final Widget child; | 7 | final Widget child; |
8 | 8 | ||
9 | - const WebFrame({Key? key, required this.child}) : super(key: key); | 9 | + const WebFrame({super.key, required this.child}); |
10 | 10 | ||
11 | @override | 11 | @override |
12 | Widget build(BuildContext context) { | 12 | Widget build(BuildContext context) { |
@@ -37,10 +37,10 @@ packages: | @@ -37,10 +37,10 @@ packages: | ||
37 | dependency: transitive | 37 | dependency: transitive |
38 | description: | 38 | description: |
39 | name: collection | 39 | name: collection |
40 | - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 | 40 | + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a |
41 | url: "https://pub.dev" | 41 | url: "https://pub.dev" |
42 | source: hosted | 42 | source: hosted |
43 | - version: "1.17.2" | 43 | + version: "1.18.0" |
44 | cupertino_icons: | 44 | cupertino_icons: |
45 | dependency: "direct main" | 45 | dependency: "direct main" |
46 | description: | 46 | description: |
@@ -72,6 +72,14 @@ packages: | @@ -72,6 +72,14 @@ packages: | ||
72 | description: flutter | 72 | description: flutter |
73 | source: sdk | 73 | source: sdk |
74 | version: "0.0.0" | 74 | version: "0.0.0" |
75 | + lints: | ||
76 | + dependency: "direct dev" | ||
77 | + description: | ||
78 | + name: lints | ||
79 | + sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 | ||
80 | + url: "https://pub.dev" | ||
81 | + source: hosted | ||
82 | + version: "3.0.0" | ||
75 | matcher: | 83 | matcher: |
76 | dependency: transitive | 84 | dependency: transitive |
77 | description: | 85 | description: |
@@ -92,10 +100,10 @@ packages: | @@ -92,10 +100,10 @@ packages: | ||
92 | dependency: transitive | 100 | dependency: transitive |
93 | description: | 101 | description: |
94 | name: meta | 102 | name: meta |
95 | - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" | 103 | + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e |
96 | url: "https://pub.dev" | 104 | url: "https://pub.dev" |
97 | source: hosted | 105 | source: hosted |
98 | - version: "1.9.1" | 106 | + version: "1.10.0" |
99 | modal_bottom_sheet: | 107 | modal_bottom_sheet: |
100 | dependency: "direct main" | 108 | dependency: "direct main" |
101 | description: | 109 | description: |
@@ -136,18 +144,18 @@ packages: | @@ -136,18 +144,18 @@ packages: | ||
136 | dependency: transitive | 144 | dependency: transitive |
137 | description: | 145 | description: |
138 | name: stack_trace | 146 | name: stack_trace |
139 | - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 | 147 | + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" |
140 | url: "https://pub.dev" | 148 | url: "https://pub.dev" |
141 | source: hosted | 149 | source: hosted |
142 | - version: "1.11.0" | 150 | + version: "1.11.1" |
143 | stream_channel: | 151 | stream_channel: |
144 | dependency: transitive | 152 | dependency: transitive |
145 | description: | 153 | description: |
146 | name: stream_channel | 154 | name: stream_channel |
147 | - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" | 155 | + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 |
148 | url: "https://pub.dev" | 156 | url: "https://pub.dev" |
149 | source: hosted | 157 | source: hosted |
150 | - version: "2.1.1" | 158 | + version: "2.1.2" |
151 | string_scanner: | 159 | string_scanner: |
152 | dependency: transitive | 160 | dependency: transitive |
153 | description: | 161 | description: |
@@ -168,10 +176,10 @@ packages: | @@ -168,10 +176,10 @@ packages: | ||
168 | dependency: transitive | 176 | dependency: transitive |
169 | description: | 177 | description: |
170 | name: test_api | 178 | name: test_api |
171 | - sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" | 179 | + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" |
172 | url: "https://pub.dev" | 180 | url: "https://pub.dev" |
173 | source: hosted | 181 | source: hosted |
174 | - version: "0.6.0" | 182 | + version: "0.6.1" |
175 | url_launcher: | 183 | url_launcher: |
176 | dependency: "direct main" | 184 | dependency: "direct main" |
177 | description: | 185 | description: |
@@ -248,10 +256,10 @@ packages: | @@ -248,10 +256,10 @@ packages: | ||
248 | dependency: transitive | 256 | dependency: transitive |
249 | description: | 257 | description: |
250 | name: web | 258 | name: web |
251 | - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 | 259 | + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 |
252 | url: "https://pub.dev" | 260 | url: "https://pub.dev" |
253 | source: hosted | 261 | source: hosted |
254 | - version: "0.1.4-beta" | 262 | + version: "0.3.0" |
255 | sdks: | 263 | sdks: |
256 | - dart: ">=3.1.0 <4.0.0" | 264 | + dart: ">=3.2.0-194.0.dev <4.0.0" |
257 | flutter: ">=3.13.0" | 265 | flutter: ">=3.13.0" |
1 | name: example | 1 | name: example |
2 | description: A new Flutter project. | 2 | description: A new Flutter project. |
3 | publish_to: none | 3 | publish_to: none |
4 | -# The following defines the version and build number for your application. | ||
5 | -# A version number is three numbers separated by dots, like 1.2.43 | ||
6 | -# followed by an optional build number separated by a +. | ||
7 | -# Both the version and the builder number may be overridden in flutter | ||
8 | -# build by specifying --build-name and --build-number, respectively. | ||
9 | -# In Android, build-name is used as versionName while build-number used as versionCode. | ||
10 | -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning | ||
11 | -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. | ||
12 | -# Read more about iOS versioning at | ||
13 | -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html | ||
14 | version: 1.0.0+1 | 4 | version: 1.0.0+1 |
15 | 5 | ||
16 | environment: | 6 | environment: |
17 | - sdk: '>=2.17.0 <3.0.0' | ||
18 | - flutter: ">=3.7.0" | ||
19 | - | 7 | + sdk: ">=3.0.0 <4.0.0" |
20 | 8 | ||
21 | dependencies: | 9 | dependencies: |
22 | - cupertino_icons: ^1.0.5 | 10 | + cupertino_icons: ^1.0.6 |
23 | flutter: | 11 | flutter: |
24 | sdk: flutter | 12 | sdk: flutter |
25 | modal_bottom_sheet: | 13 | modal_bottom_sheet: |
26 | path: '../' | 14 | path: '../' |
27 | - url_launcher: ^6.1.5 | 15 | + url_launcher: ^6.2.1 |
28 | 16 | ||
29 | dev_dependencies: | 17 | dev_dependencies: |
30 | flutter_test: | 18 | flutter_test: |
31 | sdk: flutter | 19 | sdk: flutter |
20 | + lints: ^3.0.0 | ||
32 | 21 | ||
33 | -# For information on the generic Dart part of this file, see the | ||
34 | -# following page: https://dart.dev/tools/pub/pubspec | ||
35 | 22 | ||
36 | -# The following section is specific to Flutter. | ||
37 | flutter: | 23 | flutter: |
38 | - | ||
39 | - # The following line ensures that the Material Icons font is | ||
40 | - # included with your application, so that you can use the icons in | ||
41 | - # the material Icons class. | ||
42 | uses-material-design: true | 24 | uses-material-design: true |
43 | - | ||
44 | assets: | 25 | assets: |
45 | - - assets/ | ||
46 | - # To add assets to your application, add an assets section, like this: | ||
47 | - # assets: | ||
48 | - # - images/a_dot_burr.jpeg | ||
49 | - # - images/a_dot_ham.jpeg | ||
50 | - | ||
51 | - # An image asset can refer to one or more resolution-specific "variants", see | ||
52 | - # https://flutter.dev/assets-and-images/#resolution-aware. | ||
53 | - | ||
54 | - # For details regarding adding assets from package dependencies, see | ||
55 | - # https://flutter.dev/assets-and-images/#from-packages | ||
56 | - | ||
57 | - # To add custom fonts to your application, add a fonts section here, | ||
58 | - # in this "flutter" section. Each entry in this list should have a | ||
59 | - # "family" key with the font family name, and a "fonts" key with a | ||
60 | - # list giving the asset and other descriptors for the font. For | ||
61 | - # example: | ||
62 | - # fonts: | ||
63 | - # - family: Schyler | ||
64 | - # fonts: | ||
65 | - # - asset: fonts/Schyler-Regular.ttf | ||
66 | - # - asset: fonts/Schyler-Italic.ttf | ||
67 | - # style: italic | ||
68 | - # - family: Trajan Pro | ||
69 | - # fonts: | ||
70 | - # - asset: fonts/TrajanPro.ttf | ||
71 | - # - asset: fonts/TrajanPro_Bold.ttf | ||
72 | - # weight: 700 | ||
73 | - # | ||
74 | - # For details regarding fonts from package dependencies, | ||
75 | - # see https://flutter.dev/custom-fonts/#from-packages | 26 | + - assets/ |
@@ -47,7 +47,7 @@ class ModalBottomSheet extends StatefulWidget { | @@ -47,7 +47,7 @@ class ModalBottomSheet extends StatefulWidget { | ||
47 | this.minFlingVelocity = _minFlingVelocity, | 47 | this.minFlingVelocity = _minFlingVelocity, |
48 | double? closeProgressThreshold, | 48 | double? closeProgressThreshold, |
49 | this.willPopThreshold = _willPopThreshold, | 49 | this.willPopThreshold = _willPopThreshold, |
50 | - }) : closeProgressThreshold = | 50 | + }) : closeProgressThreshold = |
51 | closeProgressThreshold ?? _closeProgressThreshold; | 51 | closeProgressThreshold ?? _closeProgressThreshold; |
52 | 52 | ||
53 | /// The closeProgressThreshold parameter | 53 | /// The closeProgressThreshold parameter |
@@ -231,7 +231,6 @@ class ModalBottomSheetState extends State<ModalBottomSheet> | @@ -231,7 +231,6 @@ class ModalBottomSheetState extends State<ModalBottomSheet> | ||
231 | 231 | ||
232 | if (_dismissUnderway || !isDragging) return; | 232 | if (_dismissUnderway || !isDragging) return; |
233 | isDragging = false; | 233 | isDragging = false; |
234 | - // ignore: unawaited_futures | ||
235 | _bounceDragController.reverse(); | 234 | _bounceDragController.reverse(); |
236 | 235 | ||
237 | Future<void> tryClose() async { | 236 | Future<void> tryClose() async { |
@@ -251,7 +250,6 @@ class ModalBottomSheetState extends State<ModalBottomSheet> | @@ -251,7 +250,6 @@ class ModalBottomSheetState extends State<ModalBottomSheet> | ||
251 | tryClose(); | 250 | tryClose(); |
252 | } else if (hasReachedCloseThreshold) { | 251 | } else if (hasReachedCloseThreshold) { |
253 | if (widget.animationController.value > 0.0) { | 252 | if (widget.animationController.value > 0.0) { |
254 | - // ignore: unawaited_futures | ||
255 | widget.animationController.fling(velocity: -1.0); | 253 | widget.animationController.fling(velocity: -1.0); |
256 | } | 254 | } |
257 | tryClose(); | 255 | tryClose(); |
@@ -273,13 +271,11 @@ class ModalBottomSheetState extends State<ModalBottomSheet> | @@ -273,13 +271,11 @@ class ModalBottomSheetState extends State<ModalBottomSheet> | ||
273 | if (!_scrollController.hasClients) return; | 271 | if (!_scrollController.hasClients) return; |
274 | 272 | ||
275 | ScrollPosition scrollPosition; | 273 | ScrollPosition scrollPosition; |
276 | - // ignore: invalid_use_of_protected_member | 274 | + |
277 | if (_scrollController.positions.length > 1) { | 275 | if (_scrollController.positions.length > 1) { |
278 | - // ignore: invalid_use_of_protected_member | ||
279 | - scrollPosition = _scrollController.positions | ||
280 | - .firstWhere((p) => p.isScrollingNotifier.value, | ||
281 | - // ignore: invalid_use_of_protected_member | ||
282 | - orElse: () => _scrollController.positions.first); | 276 | + scrollPosition = _scrollController.positions.firstWhere( |
277 | + (p) => p.isScrollingNotifier.value, | ||
278 | + orElse: () => _scrollController.positions.first); | ||
283 | } else { | 279 | } else { |
284 | scrollPosition = _scrollController.position; | 280 | scrollPosition = _scrollController.position; |
285 | } | 281 | } |
@@ -412,9 +408,15 @@ class ModalBottomSheetState extends State<ModalBottomSheet> | @@ -412,9 +408,15 @@ class ModalBottomSheetState extends State<ModalBottomSheet> | ||
412 | child: RepaintBoundary(child: child), | 408 | child: RepaintBoundary(child: child), |
413 | ); | 409 | ); |
414 | 410 | ||
415 | - return ScrollToTopStatusBarHandler( | 411 | + return StatusBarGestureDetector( |
416 | child: child, | 412 | child: child, |
417 | - scrollController: _scrollController, | 413 | + onTap: (context) { |
414 | + _scrollController.animateTo( | ||
415 | + 0.0, | ||
416 | + duration: const Duration(milliseconds: 1000), | ||
417 | + curve: Curves.easeOutCirc, | ||
418 | + ); | ||
419 | + }, | ||
418 | ); | 420 | ); |
419 | } | 421 | } |
420 | } | 422 | } |
@@ -395,7 +395,7 @@ class CupertinoScaffoldInheirted extends InheritedWidget { | @@ -395,7 +395,7 @@ class CupertinoScaffoldInheirted extends InheritedWidget { | ||
395 | required super.child, | 395 | required super.child, |
396 | this.topRadius, | 396 | this.topRadius, |
397 | required this.transitionBackgroundColor, | 397 | required this.transitionBackgroundColor, |
398 | - }) : super(); | 398 | + }); |
399 | 399 | ||
400 | @override | 400 | @override |
401 | bool updateShouldNotify(InheritedWidget oldWidget) { | 401 | bool updateShouldNotify(InheritedWidget oldWidget) { |
1 | -import 'package:flutter/widgets.dart'; | 1 | +import 'package:flutter/material.dart'; |
2 | 2 | ||
3 | -/// Widget that that will scroll to the top the ScrollController | 3 | +typedef StatusBarGestureDetectorCallback = void Function(BuildContext context); |
4 | + | ||
5 | +/// Widget that that will make the [scrollController] to scroll the top | ||
4 | /// when tapped on the status bar | 6 | /// when tapped on the status bar |
5 | /// | 7 | /// |
6 | -/// Extracted from Scaffold and used in modal bottom sheet | ||
7 | -class ScrollToTopStatusBarHandler extends StatefulWidget { | ||
8 | - final Widget child; | ||
9 | - final ScrollController scrollController; | ||
10 | - | ||
11 | - const ScrollToTopStatusBarHandler({ | 8 | +/// Extracted from [Scaffold] and used in [Sheet] |
9 | +class StatusBarGestureDetector extends StatefulWidget { | ||
10 | + const StatusBarGestureDetector({ | ||
12 | super.key, | 11 | super.key, |
13 | required this.child, | 12 | required this.child, |
14 | - required this.scrollController, | 13 | + required this.onTap, |
15 | }); | 14 | }); |
16 | 15 | ||
16 | + final Widget child; | ||
17 | + | ||
18 | + final StatusBarGestureDetectorCallback onTap; | ||
19 | + | ||
17 | @override | 20 | @override |
18 | - ScrollToTopStatusBarState createState() => ScrollToTopStatusBarState(); | 21 | + State<StatusBarGestureDetector> createState() => |
22 | + _StatusBarGestureDetectorState(); | ||
19 | } | 23 | } |
20 | 24 | ||
21 | -class ScrollToTopStatusBarState extends State<ScrollToTopStatusBarHandler> { | 25 | +class _StatusBarGestureDetectorState extends State<StatusBarGestureDetector> { |
26 | + final OverlayPortalController controller = OverlayPortalController(); | ||
27 | + | ||
22 | @override | 28 | @override |
23 | void initState() { | 29 | void initState() { |
30 | + controller.show(); | ||
24 | super.initState(); | 31 | super.initState(); |
25 | } | 32 | } |
26 | 33 | ||
27 | @override | 34 | @override |
28 | Widget build(BuildContext context) { | 35 | Widget build(BuildContext context) { |
29 | - return Stack( | ||
30 | - fit: StackFit.expand, | ||
31 | - children: [ | ||
32 | - widget.child, | ||
33 | - Positioned( | ||
34 | - top: 0, | ||
35 | - left: 0, | ||
36 | - right: 0, | ||
37 | - height: MediaQuery.of(context).padding.top, | ||
38 | - child: Builder( | ||
39 | - builder: (context) => GestureDetector( | 36 | + final view = View.of(context); |
37 | + return OverlayPortal.targetsRootOverlay( | ||
38 | + controller: controller, | ||
39 | + overlayChildBuilder: (context) { | ||
40 | + return Align( | ||
41 | + alignment: Alignment.topCenter, | ||
42 | + child: SizedBox( | ||
43 | + height: view.padding.top / view.devicePixelRatio, | ||
44 | + width: double.infinity, | ||
45 | + child: GestureDetector( | ||
40 | behavior: HitTestBehavior.opaque, | 46 | behavior: HitTestBehavior.opaque, |
41 | - onTap: () => _handleStatusBarTap(context), | 47 | + onTap: () => widget.onTap(context), |
42 | // iOS accessibility automatically adds scroll-to-top to the clock in the status bar | 48 | // iOS accessibility automatically adds scroll-to-top to the clock in the status bar |
43 | excludeFromSemantics: true, | 49 | excludeFromSemantics: true, |
44 | ), | 50 | ), |
45 | ), | 51 | ), |
46 | - ), | ||
47 | - ], | 52 | + ); |
53 | + }, | ||
54 | + child: widget.child, | ||
48 | ); | 55 | ); |
49 | } | 56 | } |
50 | - | ||
51 | - void _handleStatusBarTap(BuildContext context) { | ||
52 | - final controller = widget.scrollController; | ||
53 | - if (controller.hasClients) { | ||
54 | - controller.animateTo( | ||
55 | - 0.0, | ||
56 | - duration: const Duration(milliseconds: 300), | ||
57 | - curve: Curves.linear, // TODO(ianh): Use a more appropriate curve. | ||
58 | - ); | ||
59 | - } | ||
60 | - } | ||
61 | } | 57 | } |
sheet/example/analysis_options.yaml
0 → 100644
1 | +include: package:lints/recommended.yaml |
@@ -127,7 +127,7 @@ | @@ -127,7 +127,7 @@ | ||
127 | 97C146E61CF9000F007C117D /* Project object */ = { | 127 | 97C146E61CF9000F007C117D /* Project object */ = { |
128 | isa = PBXProject; | 128 | isa = PBXProject; |
129 | attributes = { | 129 | attributes = { |
130 | - LastUpgradeCheck = 1300; | 130 | + LastUpgradeCheck = 1430; |
131 | ORGANIZATIONNAME = ""; | 131 | ORGANIZATIONNAME = ""; |
132 | TargetAttributes = { | 132 | TargetAttributes = { |
133 | 97C146ED1CF9000F007C117D = { | 133 | 97C146ED1CF9000F007C117D = { |
@@ -3,15 +3,14 @@ import 'package:flutter/material.dart'; | @@ -3,15 +3,14 @@ import 'package:flutter/material.dart'; | ||
3 | 3 | ||
4 | class ExampleTile extends StatelessWidget { | 4 | class ExampleTile extends StatelessWidget { |
5 | const ExampleTile({ | 5 | const ExampleTile({ |
6 | - Key? key, | 6 | + super.key, |
7 | required this.title, | 7 | required this.title, |
8 | required this.page, | 8 | required this.page, |
9 | this.leading, | 9 | this.leading, |
10 | - }) : super(key: key); | 10 | + }); |
11 | 11 | ||
12 | ExampleTile.sheet(this.title, Widget sheet, {this.leading}) | 12 | ExampleTile.sheet(this.title, Widget sheet, {this.leading}) |
13 | - : page = BaseScaffold(title: Text(title), sheet: sheet), | ||
14 | - super(); | 13 | + : page = BaseScaffold(title: Text(title), sheet: sheet); |
15 | 14 | ||
16 | final String title; | 15 | final String title; |
17 | final Widget page; | 16 | final Widget page; |
@@ -33,11 +32,11 @@ class ExampleTile extends StatelessWidget { | @@ -33,11 +32,11 @@ class ExampleTile extends StatelessWidget { | ||
33 | 32 | ||
34 | class BaseScaffold extends StatelessWidget { | 33 | class BaseScaffold extends StatelessWidget { |
35 | const BaseScaffold({ | 34 | const BaseScaffold({ |
36 | - Key? key, | 35 | + super.key, |
37 | this.sheet, | 36 | this.sheet, |
38 | this.title, | 37 | this.title, |
39 | this.appBarTrailingButton, | 38 | this.appBarTrailingButton, |
40 | - }) : super(key: key); | 39 | + }); |
41 | 40 | ||
42 | final Widget? sheet; | 41 | final Widget? sheet; |
43 | final Widget? title; | 42 | final Widget? title; |
@@ -142,7 +142,7 @@ class FilterEditor extends StatelessWidget { | @@ -142,7 +142,7 @@ class FilterEditor extends StatelessWidget { | ||
142 | ), | 142 | ), |
143 | ), | 143 | ), |
144 | ], | 144 | ], |
145 | - ).toList(), | 145 | + ), |
146 | const SectionTitle('Appareance'), | 146 | const SectionTitle('Appareance'), |
147 | ...ListTile.divideTiles( | 147 | ...ListTile.divideTiles( |
148 | context: context, | 148 | context: context, |
@@ -221,7 +221,7 @@ class FilterEditor extends StatelessWidget { | @@ -221,7 +221,7 @@ class FilterEditor extends StatelessWidget { | ||
221 | }), | 221 | }), |
222 | ), | 222 | ), |
223 | ], | 223 | ], |
224 | - ).toList(), | 224 | + ), |
225 | const SectionTitle('Physics'), | 225 | const SectionTitle('Physics'), |
226 | ...ListTile.divideTiles( | 226 | ...ListTile.divideTiles( |
227 | context: context, | 227 | context: context, |
@@ -251,7 +251,7 @@ class FilterEditor extends StatelessWidget { | @@ -251,7 +251,7 @@ class FilterEditor extends StatelessWidget { | ||
251 | ), | 251 | ), |
252 | ), | 252 | ), |
253 | ], | 253 | ], |
254 | - ).toList(), | 254 | + ), |
255 | ]), | 255 | ]), |
256 | ), | 256 | ), |
257 | ); | 257 | ); |
@@ -259,8 +259,7 @@ class FilterEditor extends StatelessWidget { | @@ -259,8 +259,7 @@ class FilterEditor extends StatelessWidget { | ||
259 | } | 259 | } |
260 | 260 | ||
261 | class NumTextField extends StatelessWidget { | 261 | class NumTextField extends StatelessWidget { |
262 | - const NumTextField({Key? key, this.onChanged, this.maxNumber = 999}) | ||
263 | - : super(key: key); | 262 | + const NumTextField({super.key, this.onChanged, this.maxNumber = 999}); |
264 | final ValueChanged<int?>? onChanged; | 263 | final ValueChanged<int?>? onChanged; |
265 | final int maxNumber; | 264 | final int maxNumber; |
266 | @override | 265 | @override |
@@ -318,8 +317,8 @@ class NumericalRangeFormatter extends TextInputFormatter { | @@ -318,8 +317,8 @@ class NumericalRangeFormatter extends TextInputFormatter { | ||
318 | class SectionTitle extends StatelessWidget { | 317 | class SectionTitle extends StatelessWidget { |
319 | const SectionTitle( | 318 | const SectionTitle( |
320 | this.text, { | 319 | this.text, { |
321 | - Key? key, | ||
322 | - }) : super(key: key); | 320 | + super.key, |
321 | + }); | ||
323 | 322 | ||
324 | final String text; | 323 | final String text; |
325 | 324 |
@@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; | @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; | ||
3 | import 'package:sheet/route.dart'; | 3 | import 'package:sheet/route.dart'; |
4 | 4 | ||
5 | class ModalInsideModal extends StatelessWidget { | 5 | class ModalInsideModal extends StatelessWidget { |
6 | - const ModalInsideModal({Key? key, this.reverse = false}) : super(key: key); | 6 | + const ModalInsideModal({super.key, this.reverse = false}); |
7 | final bool reverse; | 7 | final bool reverse; |
8 | 8 | ||
9 | @override | 9 | @override |
@@ -2,8 +2,7 @@ import 'package:flutter/cupertino.dart'; | @@ -2,8 +2,7 @@ import 'package:flutter/cupertino.dart'; | ||
2 | import 'package:flutter/material.dart'; | 2 | import 'package:flutter/material.dart'; |
3 | 3 | ||
4 | class SimpleModal extends StatelessWidget { | 4 | class SimpleModal extends StatelessWidget { |
5 | - const SimpleModal({Key? key, required this.scrollController}) | ||
6 | - : super(key: key); | 5 | + const SimpleModal({super.key, required this.scrollController}); |
7 | final ScrollController scrollController; | 6 | final ScrollController scrollController; |
8 | 7 | ||
9 | @override | 8 | @override |
@@ -24,8 +24,7 @@ class AvatarSheetRoute<T> extends SheetRoute<T> { | @@ -24,8 +24,7 @@ class AvatarSheetRoute<T> extends SheetRoute<T> { | ||
24 | } | 24 | } |
25 | 25 | ||
26 | class _AvatarSheet extends StatelessWidget { | 26 | class _AvatarSheet extends StatelessWidget { |
27 | - const _AvatarSheet({Key? key, required this.child, required this.animation}) | ||
28 | - : super(key: key); | 27 | + const _AvatarSheet({required this.child, required this.animation}); |
29 | final Widget child; | 28 | final Widget child; |
30 | final Animation<double> animation; | 29 | final Animation<double> animation; |
31 | 30 |
1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
2 | import 'package:flutter/services.dart'; | 2 | import 'package:flutter/services.dart'; |
3 | import 'package:sheet/route.dart'; | 3 | import 'package:sheet/route.dart'; |
4 | -import 'package:sheet/sheet.dart'; | ||
5 | 4 | ||
6 | -const Radius _default_bar_top_radius = Radius.circular(15); | 5 | +const Radius _defaultBarTopRadius = Radius.circular(15); |
7 | 6 | ||
8 | class BarBottomSheet extends StatelessWidget { | 7 | class BarBottomSheet extends StatelessWidget { |
9 | const BarBottomSheet( | 8 | const BarBottomSheet( |
10 | - {Key? key, | 9 | + {super.key, |
11 | required this.child, | 10 | required this.child, |
12 | this.control, | 11 | this.control, |
13 | this.clipBehavior, | 12 | this.clipBehavior, |
14 | this.shape, | 13 | this.shape, |
15 | - this.elevation}) | ||
16 | - : super(key: key); | 14 | + this.elevation}); |
17 | final Widget child; | 15 | final Widget child; |
18 | final Widget? control; | 16 | final Widget? control; |
19 | final Clip? clipBehavior; | 17 | final Clip? clipBehavior; |
@@ -49,8 +47,8 @@ class BarBottomSheet extends StatelessWidget { | @@ -49,8 +47,8 @@ class BarBottomSheet extends StatelessWidget { | ||
49 | const RoundedRectangleBorder( | 47 | const RoundedRectangleBorder( |
50 | side: BorderSide(), | 48 | side: BorderSide(), |
51 | borderRadius: BorderRadius.only( | 49 | borderRadius: BorderRadius.only( |
52 | - topLeft: _default_bar_top_radius, | ||
53 | - topRight: _default_bar_top_radius), | 50 | + topLeft: _defaultBarTopRadius, |
51 | + topRight: _defaultBarTopRadius), | ||
54 | ), | 52 | ), |
55 | clipBehavior: clipBehavior ?? Clip.hardEdge, | 53 | clipBehavior: clipBehavior ?? Clip.hardEdge, |
56 | elevation: elevation ?? 2, | 54 | elevation: elevation ?? 2, |
@@ -72,13 +70,13 @@ class BarSheetRoute<T> extends SheetRoute<T> { | @@ -72,13 +70,13 @@ class BarSheetRoute<T> extends SheetRoute<T> { | ||
72 | double? elevation, | 70 | double? elevation, |
73 | ShapeBorder? shape, | 71 | ShapeBorder? shape, |
74 | Clip? clipBehavior, | 72 | Clip? clipBehavior, |
75 | - Color barrierColor = Colors.black87, | ||
76 | - SheetFit fit = SheetFit.expand, | ||
77 | - Curve? animationCurve, | 73 | + Color super.barrierColor = Colors.black87, |
74 | + super.fit, | ||
75 | + super.animationCurve, | ||
78 | bool isDismissible = true, | 76 | bool isDismissible = true, |
79 | bool enableDrag = true, | 77 | bool enableDrag = true, |
80 | Widget? topControl, | 78 | Widget? topControl, |
81 | - Duration? duration, | 79 | + super.duration, |
82 | }) : super( | 80 | }) : super( |
83 | builder: (BuildContext context) { | 81 | builder: (BuildContext context) { |
84 | return BarBottomSheet( | 82 | return BarBottomSheet( |
@@ -89,11 +87,7 @@ class BarSheetRoute<T> extends SheetRoute<T> { | @@ -89,11 +87,7 @@ class BarSheetRoute<T> extends SheetRoute<T> { | ||
89 | elevation: elevation, | 87 | elevation: elevation, |
90 | ); | 88 | ); |
91 | }, | 89 | }, |
92 | - fit: fit, | ||
93 | barrierDismissible: isDismissible, | 90 | barrierDismissible: isDismissible, |
94 | - barrierColor: barrierColor, | ||
95 | draggable: enableDrag, | 91 | draggable: enableDrag, |
96 | - animationCurve: animationCurve, | ||
97 | - duration: duration, | ||
98 | ); | 92 | ); |
99 | } | 93 | } |
@@ -3,8 +3,7 @@ import 'package:sheet/route.dart'; | @@ -3,8 +3,7 @@ import 'package:sheet/route.dart'; | ||
3 | import 'package:sheet/sheet.dart'; | 3 | import 'package:sheet/sheet.dart'; |
4 | 4 | ||
5 | class DialogSheet extends StatelessWidget { | 5 | class DialogSheet extends StatelessWidget { |
6 | - const DialogSheet({Key? key, required this.child, this.backgroundColor}) | ||
7 | - : super(key: key); | 6 | + const DialogSheet({super.key, required this.child, this.backgroundColor}); |
8 | final Widget child; | 7 | final Widget child; |
9 | final Color? backgroundColor; | 8 | final Color? backgroundColor; |
10 | 9 |
@@ -3,8 +3,7 @@ import 'package:sheet/route.dart'; | @@ -3,8 +3,7 @@ import 'package:sheet/route.dart'; | ||
3 | import 'package:sheet/sheet.dart'; | 3 | import 'package:sheet/sheet.dart'; |
4 | 4 | ||
5 | class FloatingModal extends StatelessWidget { | 5 | class FloatingModal extends StatelessWidget { |
6 | - const FloatingModal({Key? key, required this.child, this.backgroundColor}) | ||
7 | - : super(key: key); | 6 | + const FloatingModal({super.key, required this.child, this.backgroundColor}); |
8 | final Widget child; | 7 | final Widget child; |
9 | final Color? backgroundColor; | 8 | final Color? backgroundColor; |
10 | 9 |
1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
2 | import 'package:sheet/route.dart'; | 2 | import 'package:sheet/route.dart'; |
3 | -import 'package:sheet/sheet.dart'; | ||
4 | 3 | ||
5 | class MaterialSheetRoute<T> extends SheetRoute<T> { | 4 | class MaterialSheetRoute<T> extends SheetRoute<T> { |
6 | MaterialSheetRoute({ | 5 | MaterialSheetRoute({ |
@@ -9,14 +8,14 @@ class MaterialSheetRoute<T> extends SheetRoute<T> { | @@ -9,14 +8,14 @@ class MaterialSheetRoute<T> extends SheetRoute<T> { | ||
9 | double? elevation, | 8 | double? elevation, |
10 | ShapeBorder? shape, | 9 | ShapeBorder? shape, |
11 | Clip? clipBehavior, | 10 | Clip? clipBehavior, |
12 | - Color barrierColor = Colors.black87, | ||
13 | - SheetFit fit = SheetFit.expand, | ||
14 | - Curve? animationCurve, | ||
15 | - bool barrierDismissible = true, | 11 | + Color super.barrierColor = Colors.black87, |
12 | + super.fit, | ||
13 | + super.animationCurve, | ||
14 | + super.barrierDismissible, | ||
16 | bool enableDrag = true, | 15 | bool enableDrag = true, |
17 | - List<double>? stops, | 16 | + super.stops, |
18 | double initialStop = 1, | 17 | double initialStop = 1, |
19 | - Duration? duration, | 18 | + super.duration, |
20 | }) : super( | 19 | }) : super( |
21 | builder: (BuildContext context) => Material( | 20 | builder: (BuildContext context) => Material( |
22 | child: Builder( | 21 | child: Builder( |
@@ -27,13 +26,7 @@ class MaterialSheetRoute<T> extends SheetRoute<T> { | @@ -27,13 +26,7 @@ class MaterialSheetRoute<T> extends SheetRoute<T> { | ||
27 | shape: shape, | 26 | shape: shape, |
28 | elevation: elevation ?? 1, | 27 | elevation: elevation ?? 1, |
29 | ), | 28 | ), |
30 | - stops: stops, | ||
31 | initialExtent: initialStop, | 29 | initialExtent: initialStop, |
32 | - fit: fit, | ||
33 | - barrierDismissible: barrierDismissible, | ||
34 | - barrierColor: barrierColor, | ||
35 | draggable: enableDrag, | 30 | draggable: enableDrag, |
36 | - animationCurve: animationCurve, | ||
37 | - duration: duration, | ||
38 | ); | 31 | ); |
39 | } | 32 | } |
1 | +import 'package:collection/collection.dart'; | ||
2 | +import 'package:flutter/cupertino.dart'; | ||
3 | +import 'package:flutter/material.dart'; | ||
4 | +import 'package:go_router/go_router.dart'; | ||
5 | +import 'package:sheet/route.dart'; | ||
6 | + | ||
7 | +class Book { | ||
8 | + const Book(this.id, this.title, this.author); | ||
9 | + final String id; | ||
10 | + final String title; | ||
11 | + final String author; | ||
12 | +} | ||
13 | + | ||
14 | +class AdvancedGoRouterBooksApp extends StatefulWidget { | ||
15 | + @override | ||
16 | + State<StatefulWidget> createState() => _GoRouterBooksAppState(); | ||
17 | +} | ||
18 | + | ||
19 | +class _GoRouterBooksAppState extends State<AdvancedGoRouterBooksApp> { | ||
20 | + List<Book> books = <Book>[ | ||
21 | + const Book('1', 'Stranger in a Strange Land', 'Robert A. Heinlein'), | ||
22 | + const Book('2', 'Foundation', 'Isaac Asimov'), | ||
23 | + const Book('3', 'Fahrenheit 451', 'Ray Bradbury'), | ||
24 | + ]; | ||
25 | + | ||
26 | + @override | ||
27 | + void initState() { | ||
28 | + super.initState(); | ||
29 | + } | ||
30 | + | ||
31 | + Brightness brightness = Brightness.light; | ||
32 | + | ||
33 | + @override | ||
34 | + Widget build(BuildContext context) { | ||
35 | + return MaterialApp.router( | ||
36 | + routeInformationProvider: _router.routeInformationProvider, | ||
37 | + routeInformationParser: _router.routeInformationParser, | ||
38 | + routerDelegate: _router.routerDelegate, | ||
39 | + debugShowCheckedModeBanner: false, | ||
40 | + theme: | ||
41 | + brightness == Brightness.light ? ThemeData.light() : ThemeData.dark(), | ||
42 | + title: 'Books App', | ||
43 | + builder: (BuildContext context, Widget? child) { | ||
44 | + return CupertinoTheme( | ||
45 | + data: CupertinoThemeData(brightness: brightness), | ||
46 | + child: child!, | ||
47 | + ); | ||
48 | + }, | ||
49 | + ); | ||
50 | + } | ||
51 | + | ||
52 | + final rootNavigatorKey = GlobalKey<NavigatorState>(); | ||
53 | + final nestedNavigationKey = GlobalKey<NavigatorState>(); | ||
54 | + late final GoRouter _router = GoRouter( | ||
55 | + debugLogDiagnostics: true, | ||
56 | + navigatorKey: rootNavigatorKey, | ||
57 | + routes: <GoRoute>[ | ||
58 | + GoRoute( | ||
59 | + path: '/', | ||
60 | + pageBuilder: (BuildContext context, GoRouterState state) { | ||
61 | + return MaterialExtendedPage<void>( | ||
62 | + key: state.pageKey, | ||
63 | + child: BooksListScreen( | ||
64 | + books: books, | ||
65 | + onBrigthnessChanged: (Brightness brightness) { | ||
66 | + setState(() { | ||
67 | + this.brightness = brightness; | ||
68 | + }); | ||
69 | + }, | ||
70 | + ), | ||
71 | + ); | ||
72 | + }, | ||
73 | + routes: <RouteBase>[ | ||
74 | + ShellRoute( | ||
75 | + navigatorKey: nestedNavigationKey, | ||
76 | + parentNavigatorKey: rootNavigatorKey, | ||
77 | + pageBuilder: (context, state, child) { | ||
78 | + return CupertinoSheetPage<void>(child: child); | ||
79 | + }, | ||
80 | + routes: [ | ||
81 | + GoRoute( | ||
82 | + name: 'book', | ||
83 | + path: 'book/:bid', | ||
84 | + parentNavigatorKey: nestedNavigationKey, | ||
85 | + pageBuilder: (BuildContext context, GoRouterState state) { | ||
86 | + final String id = state.pathParameters['bid']!; | ||
87 | + final Book? book = | ||
88 | + books.firstWhereOrNull((Book b) => b.id == id); | ||
89 | + return MaterialPage<void>( | ||
90 | + key: state.pageKey, | ||
91 | + child: BookDetailsScreen( | ||
92 | + book: book!, | ||
93 | + ), | ||
94 | + ); | ||
95 | + }, | ||
96 | + redirect: (context, state) { | ||
97 | + final String id = state.pathParameters['bid']!; | ||
98 | + final Book? book = | ||
99 | + books.firstWhereOrNull((Book b) => b.id == id); | ||
100 | + if (book == null) { | ||
101 | + return '/404'; | ||
102 | + } | ||
103 | + // no need to redirect at all | ||
104 | + return null; | ||
105 | + }, | ||
106 | + routes: [ | ||
107 | + GoRoute( | ||
108 | + name: 'Reviews', | ||
109 | + path: 'reviews', | ||
110 | + parentNavigatorKey: nestedNavigationKey, | ||
111 | + pageBuilder: (context, state) { | ||
112 | + return MaterialPage<void>( | ||
113 | + key: state.pageKey, | ||
114 | + child: Scaffold( | ||
115 | + appBar: AppBar( | ||
116 | + title: const Text('Reviews'), | ||
117 | + ), | ||
118 | + ), | ||
119 | + ); | ||
120 | + }, | ||
121 | + ), | ||
122 | + ]), | ||
123 | + ]), | ||
124 | + GoRoute( | ||
125 | + name: 'new', | ||
126 | + path: 'new', | ||
127 | + parentNavigatorKey: rootNavigatorKey, | ||
128 | + pageBuilder: (BuildContext context, GoRouterState state) { | ||
129 | + return CupertinoSheetPage<void>( | ||
130 | + key: state.pageKey, | ||
131 | + child: Scaffold( | ||
132 | + backgroundColor: Colors.grey[200], | ||
133 | + appBar: AppBar( | ||
134 | + title: const Text('New'), | ||
135 | + ), | ||
136 | + ), | ||
137 | + ); | ||
138 | + }, | ||
139 | + ), | ||
140 | + ]), | ||
141 | + ], | ||
142 | + ); | ||
143 | +} | ||
144 | + | ||
145 | +class BooksListScreen extends StatelessWidget { | ||
146 | + const BooksListScreen({ | ||
147 | + required this.books, | ||
148 | + required this.onBrigthnessChanged, | ||
149 | + }); | ||
150 | + final List<Book> books; | ||
151 | + | ||
152 | + final void Function(Brightness) onBrigthnessChanged; | ||
153 | + | ||
154 | + @override | ||
155 | + Widget build(BuildContext context) { | ||
156 | + final Brightness brightness = Theme.of(context).brightness; | ||
157 | + return Scaffold( | ||
158 | + appBar: CupertinoNavigationBar( | ||
159 | + leading: BackButton(onPressed: () { | ||
160 | + Navigator.of(context, rootNavigator: true).pop(); | ||
161 | + }), | ||
162 | + middle: const Text('Book'), | ||
163 | + trailing: IconButton( | ||
164 | + icon: Icon(brightness == Brightness.light | ||
165 | + ? Icons.nightlight_round | ||
166 | + : Icons.wb_sunny), | ||
167 | + onPressed: () { | ||
168 | + onBrigthnessChanged( | ||
169 | + brightness == Brightness.light | ||
170 | + ? Brightness.dark | ||
171 | + : Brightness.light, | ||
172 | + ); | ||
173 | + }, | ||
174 | + ), | ||
175 | + ), | ||
176 | + body: SafeArea( | ||
177 | + child: ListView( | ||
178 | + children: <Widget>[ | ||
179 | + for (Book book in books) | ||
180 | + ListTile( | ||
181 | + title: Text(book.title), | ||
182 | + subtitle: Text(book.author), | ||
183 | + onTap: () { | ||
184 | + context.go('/book/${book.id}'); | ||
185 | + }, | ||
186 | + trailing: TextButton( | ||
187 | + onPressed: () { | ||
188 | + context.go('/book/${book.id}'); | ||
189 | + context.go('/book/${book.id}/reviews'); | ||
190 | + }, | ||
191 | + child: const Text('Reviews'), | ||
192 | + )) | ||
193 | + ], | ||
194 | + ), | ||
195 | + ), | ||
196 | + ); | ||
197 | + } | ||
198 | +} | ||
199 | + | ||
200 | +class BookDetailsScreen extends StatelessWidget { | ||
201 | + const BookDetailsScreen({ | ||
202 | + required this.book, | ||
203 | + }); | ||
204 | + final Book book; | ||
205 | + | ||
206 | + @override | ||
207 | + Widget build(BuildContext context) { | ||
208 | + return Scaffold( | ||
209 | + appBar: const CupertinoNavigationBar( | ||
210 | + middle: Text('Book'), | ||
211 | + ), | ||
212 | + body: Padding( | ||
213 | + padding: const EdgeInsets.all(8.0) + const EdgeInsets.only(top: 52.0), | ||
214 | + child: Column( | ||
215 | + crossAxisAlignment: CrossAxisAlignment.stretch, | ||
216 | + children: <Widget>[ | ||
217 | + Text(book.title, style: Theme.of(context).textTheme.titleLarge), | ||
218 | + Text(book.author, style: Theme.of(context).textTheme.titleMedium), | ||
219 | + TextButton( | ||
220 | + onPressed: () { | ||
221 | + context.go('/book/${book.id}/reviews'); | ||
222 | + }, | ||
223 | + child: Text('Reviews'), | ||
224 | + ) | ||
225 | + ], | ||
226 | + ), | ||
227 | + ), | ||
228 | + floatingActionButton: FloatingActionButton( | ||
229 | + child: const Icon(Icons.add), | ||
230 | + onPressed: () { | ||
231 | + context.push('/new'); | ||
232 | + }, | ||
233 | + ), | ||
234 | + ); | ||
235 | + } | ||
236 | +} |
@@ -20,7 +20,7 @@ class BounceTopSheet extends StatelessWidget { | @@ -20,7 +20,7 @@ class BounceTopSheet extends StatelessWidget { | ||
20 | 20 | ||
21 | class BouncingSheetPage extends StatefulWidget { | 21 | class BouncingSheetPage extends StatefulWidget { |
22 | @override | 22 | @override |
23 | - _BouncingSheetPageState createState() => _BouncingSheetPageState(); | 23 | + State<BouncingSheetPage> createState() => _BouncingSheetPageState(); |
24 | } | 24 | } |
25 | 25 | ||
26 | class _BouncingSheetPageState extends State<BouncingSheetPage> { | 26 | class _BouncingSheetPageState extends State<BouncingSheetPage> { |
@@ -6,7 +6,7 @@ import 'package:sheet/sheet.dart'; | @@ -6,7 +6,7 @@ import 'package:sheet/sheet.dart'; | ||
6 | 6 | ||
7 | class ClampedSheet extends StatefulWidget { | 7 | class ClampedSheet extends StatefulWidget { |
8 | @override | 8 | @override |
9 | - _ClampedSheetState createState() => _ClampedSheetState(); | 9 | + State<ClampedSheet> createState() => _ClampedSheetState(); |
10 | } | 10 | } |
11 | 11 | ||
12 | class _ClampedSheetState extends State<ClampedSheet> { | 12 | class _ClampedSheetState extends State<ClampedSheet> { |
@@ -8,7 +8,7 @@ import 'package:sheet/sheet.dart'; | @@ -8,7 +8,7 @@ import 'package:sheet/sheet.dart'; | ||
8 | 8 | ||
9 | class AdvancedSnapSheetPage extends StatefulWidget { | 9 | class AdvancedSnapSheetPage extends StatefulWidget { |
10 | @override | 10 | @override |
11 | - _AdvancedSnapSheetPageState createState() => _AdvancedSnapSheetPageState(); | 11 | + State<AdvancedSnapSheetPage> createState() => _AdvancedSnapSheetPageState(); |
12 | } | 12 | } |
13 | 13 | ||
14 | class _AdvancedSnapSheetPageState extends State<AdvancedSnapSheetPage> | 14 | class _AdvancedSnapSheetPageState extends State<AdvancedSnapSheetPage> |
@@ -71,7 +71,7 @@ class _AdvancedSnapSheetPageState extends State<AdvancedSnapSheetPage> | @@ -71,7 +71,7 @@ class _AdvancedSnapSheetPageState extends State<AdvancedSnapSheetPage> | ||
71 | } | 71 | } |
72 | 72 | ||
73 | class MapAppBar extends StatefulWidget implements PreferredSizeWidget { | 73 | class MapAppBar extends StatefulWidget implements PreferredSizeWidget { |
74 | - const MapAppBar({Key? key, required this.controller}) : super(key: key); | 74 | + const MapAppBar({super.key, required this.controller}); |
75 | final SheetController controller; | 75 | final SheetController controller; |
76 | @override | 76 | @override |
77 | Size get preferredSize => Size.fromHeight(kToolbarHeight); | 77 | Size get preferredSize => Size.fromHeight(kToolbarHeight); |
@@ -174,7 +174,7 @@ class _MapAppBarState extends State<MapAppBar> { | @@ -174,7 +174,7 @@ class _MapAppBarState extends State<MapAppBar> { | ||
174 | } | 174 | } |
175 | 175 | ||
176 | class FloatingButtons extends StatelessWidget { | 176 | class FloatingButtons extends StatelessWidget { |
177 | - const FloatingButtons({Key? key, required this.controller}) : super(key: key); | 177 | + const FloatingButtons({super.key, required this.controller}); |
178 | final SheetController controller; | 178 | final SheetController controller; |
179 | @override | 179 | @override |
180 | Widget build(BuildContext context) { | 180 | Widget build(BuildContext context) { |
@@ -225,7 +225,7 @@ class FloatingButtons extends StatelessWidget { | @@ -225,7 +225,7 @@ class FloatingButtons extends StatelessWidget { | ||
225 | } | 225 | } |
226 | 226 | ||
227 | class MapSheet extends StatelessWidget { | 227 | class MapSheet extends StatelessWidget { |
228 | - const MapSheet({Key? key, required this.controller}) : super(key: key); | 228 | + const MapSheet({super.key, required this.controller}); |
229 | final SheetController controller; | 229 | final SheetController controller; |
230 | @override | 230 | @override |
231 | Widget build(BuildContext context) { | 231 | Widget build(BuildContext context) { |
@@ -5,7 +5,7 @@ import 'package:sheet/sheet.dart'; | @@ -5,7 +5,7 @@ import 'package:sheet/sheet.dart'; | ||
5 | 5 | ||
6 | class FitResizableSheet extends StatefulWidget { | 6 | class FitResizableSheet extends StatefulWidget { |
7 | @override | 7 | @override |
8 | - _FitSheetState createState() => _FitSheetState(); | 8 | + State<FitResizableSheet> createState() => _FitSheetState(); |
9 | } | 9 | } |
10 | 10 | ||
11 | class _FitSheetState extends State<FitResizableSheet> { | 11 | class _FitSheetState extends State<FitResizableSheet> { |
@@ -6,7 +6,7 @@ import 'package:sheet/sheet.dart'; | @@ -6,7 +6,7 @@ import 'package:sheet/sheet.dart'; | ||
6 | 6 | ||
7 | class FitSnapSheet extends StatefulWidget { | 7 | class FitSnapSheet extends StatefulWidget { |
8 | @override | 8 | @override |
9 | - _FitSheetState createState() => _FitSheetState(); | 9 | + State<FitSnapSheet> createState() => _FitSheetState(); |
10 | } | 10 | } |
11 | 11 | ||
12 | class _FitSheetState extends State<FitSnapSheet> { | 12 | class _FitSheetState extends State<FitSnapSheet> { |
@@ -3,7 +3,7 @@ import 'package:sheet/sheet.dart'; | @@ -3,7 +3,7 @@ import 'package:sheet/sheet.dart'; | ||
3 | 3 | ||
4 | class FloatingSheet extends StatefulWidget { | 4 | class FloatingSheet extends StatefulWidget { |
5 | @override | 5 | @override |
6 | - _FitSheetState createState() => _FitSheetState(); | 6 | + State<FloatingSheet> createState() => _FitSheetState(); |
7 | } | 7 | } |
8 | 8 | ||
9 | class _FitSheetState extends State<FloatingSheet> { | 9 | class _FitSheetState extends State<FloatingSheet> { |
@@ -3,7 +3,7 @@ import 'package:sheet/sheet.dart'; | @@ -3,7 +3,7 @@ import 'package:sheet/sheet.dart'; | ||
3 | 3 | ||
4 | class FoldableScreenFloatingSheet extends StatefulWidget { | 4 | class FoldableScreenFloatingSheet extends StatefulWidget { |
5 | @override | 5 | @override |
6 | - _FitSheetState createState() => _FitSheetState(); | 6 | + State<FoldableScreenFloatingSheet> createState() => _FitSheetState(); |
7 | } | 7 | } |
8 | 8 | ||
9 | class _FitSheetState extends State<FoldableScreenFloatingSheet> { | 9 | class _FitSheetState extends State<FoldableScreenFloatingSheet> { |
@@ -6,7 +6,7 @@ import 'package:sheet/sheet.dart'; | @@ -6,7 +6,7 @@ import 'package:sheet/sheet.dart'; | ||
6 | 6 | ||
7 | class NoMomentumSheet extends StatefulWidget { | 7 | class NoMomentumSheet extends StatefulWidget { |
8 | @override | 8 | @override |
9 | - _NoMomentumSheetState createState() => _NoMomentumSheetState(); | 9 | + State<NoMomentumSheet> createState() => _NoMomentumSheetState(); |
10 | } | 10 | } |
11 | 11 | ||
12 | class _NoMomentumSheetState extends State<NoMomentumSheet> { | 12 | class _NoMomentumSheetState extends State<NoMomentumSheet> { |
@@ -6,7 +6,7 @@ import 'package:sheet/sheet.dart'; | @@ -6,7 +6,7 @@ import 'package:sheet/sheet.dart'; | ||
6 | 6 | ||
7 | class SnapSheet extends StatefulWidget { | 7 | class SnapSheet extends StatefulWidget { |
8 | @override | 8 | @override |
9 | - _SnapSheetState createState() => _SnapSheetState(); | 9 | + State<SnapSheet> createState() => _SnapSheetState(); |
10 | } | 10 | } |
11 | 11 | ||
12 | class _SnapSheetState extends State<SnapSheet> { | 12 | class _SnapSheetState extends State<SnapSheet> { |
@@ -4,7 +4,7 @@ import 'package:sheet/sheet.dart'; | @@ -4,7 +4,7 @@ import 'package:sheet/sheet.dart'; | ||
4 | 4 | ||
5 | class TextFieldSheet extends StatefulWidget { | 5 | class TextFieldSheet extends StatefulWidget { |
6 | @override | 6 | @override |
7 | - _TextFieldSheetState createState() => _TextFieldSheetState(); | 7 | + State<TextFieldSheet> createState() => _TextFieldSheetState(); |
8 | } | 8 | } |
9 | 9 | ||
10 | class _TextFieldSheetState extends State<TextFieldSheet> | 10 | class _TextFieldSheetState extends State<TextFieldSheet> |
1 | import 'package:example/route_example_page.dart'; | 1 | import 'package:example/route_example_page.dart'; |
2 | import 'package:example/sheet_example_page.dart'; | 2 | import 'package:example/sheet_example_page.dart'; |
3 | import 'package:flutter/material.dart'; | 3 | import 'package:flutter/material.dart'; |
4 | +import 'package:go_router/go_router.dart'; | ||
4 | import 'package:sheet/route.dart'; | 5 | import 'package:sheet/route.dart'; |
5 | 6 | ||
6 | void main() => runApp(MyApp()); | 7 | void main() => runApp(MyApp()); |
7 | 8 | ||
9 | +final goRouter = GoRouter(routes: [ | ||
10 | + GoRoute( | ||
11 | + path: '/', | ||
12 | + pageBuilder: (context, state) => | ||
13 | + MaterialExtendedPage<void>(child: const BottomNavigationScaffold()), | ||
14 | + ), | ||
15 | +]); | ||
16 | + | ||
8 | class MyApp extends StatelessWidget { | 17 | class MyApp extends StatelessWidget { |
9 | @override | 18 | @override |
10 | Widget build(BuildContext context) { | 19 | Widget build(BuildContext context) { |
11 | - return MaterialApp( | 20 | + return MaterialApp.router( |
12 | theme: ThemeData(platform: TargetPlatform.iOS), | 21 | theme: ThemeData(platform: TargetPlatform.iOS), |
13 | debugShowCheckedModeBanner: false, | 22 | debugShowCheckedModeBanner: false, |
14 | title: 'BottomSheet Modals', | 23 | title: 'BottomSheet Modals', |
15 | - onGenerateRoute: (RouteSettings settings) { | ||
16 | - if (settings.name == '/') { | ||
17 | - return MaterialExtendedPageRoute<void>( | ||
18 | - builder: (BuildContext context) { | ||
19 | - return const BottomNavigationScaffold(); | ||
20 | - }, | ||
21 | - ); | ||
22 | - } | ||
23 | - return null; | ||
24 | - }, | 24 | + routerConfig: goRouter, |
25 | ); | 25 | ); |
26 | } | 26 | } |
27 | } | 27 | } |
@@ -19,6 +19,7 @@ import 'package:sheet/sheet.dart'; | @@ -19,6 +19,7 @@ import 'package:sheet/sheet.dart'; | ||
19 | 19 | ||
20 | import 'examples/route/examples/modal_with_nested_scroll.dart'; | 20 | import 'examples/route/examples/modal_with_nested_scroll.dart'; |
21 | import 'examples/route/navigation/go_router.dart'; | 21 | import 'examples/route/navigation/go_router.dart'; |
22 | +import 'examples/route/navigation/go_router_advanced.dart'; | ||
22 | 23 | ||
23 | class RouteExamplePage extends StatelessWidget { | 24 | class RouteExamplePage extends StatelessWidget { |
24 | const RouteExamplePage({super.key}); | 25 | const RouteExamplePage({super.key}); |
@@ -84,6 +85,16 @@ class RouteExamplePage extends StatelessWidget { | @@ -84,6 +85,16 @@ class RouteExamplePage extends StatelessWidget { | ||
84 | ), | 85 | ), |
85 | ), | 86 | ), |
86 | ), | 87 | ), |
88 | + ListTile( | ||
89 | + title: const Text('Go router - ShellRoutes'), | ||
90 | + onTap: () => Navigator.of(context).push( | ||
91 | + MaterialPageRoute<void>( | ||
92 | + fullscreenDialog: true, | ||
93 | + builder: (BuildContext context) => | ||
94 | + AdvancedGoRouterBooksApp(), | ||
95 | + ), | ||
96 | + ), | ||
97 | + ), | ||
87 | const SectionTitle('STYLES'), | 98 | const SectionTitle('STYLES'), |
88 | ListTile( | 99 | ListTile( |
89 | title: const Text('Material fit'), | 100 | title: const Text('Material fit'), |
@@ -313,11 +324,10 @@ class RouteExamplePage extends StatelessWidget { | @@ -313,11 +324,10 @@ class RouteExamplePage extends StatelessWidget { | ||
313 | class SectionTitle extends StatelessWidget { | 324 | class SectionTitle extends StatelessWidget { |
314 | final String title; | 325 | final String title; |
315 | 326 | ||
316 | - // ignore: sort_constructors_first | ||
317 | const SectionTitle( | 327 | const SectionTitle( |
318 | this.title, { | 328 | this.title, { |
319 | - Key? key, | ||
320 | - }) : super(key: key); | 329 | + super.key, |
330 | + }); | ||
321 | @override | 331 | @override |
322 | Widget build(BuildContext context) { | 332 | Widget build(BuildContext context) { |
323 | return Padding( | 333 | return Padding( |
@@ -75,11 +75,10 @@ class SheetExamplesPage extends StatelessWidget { | @@ -75,11 +75,10 @@ class SheetExamplesPage extends StatelessWidget { | ||
75 | class SectionTitle extends StatelessWidget { | 75 | class SectionTitle extends StatelessWidget { |
76 | final String title; | 76 | final String title; |
77 | 77 | ||
78 | - // ignore: sort_constructors_first | ||
79 | const SectionTitle( | 78 | const SectionTitle( |
80 | this.title, { | 79 | this.title, { |
81 | - Key? key, | ||
82 | - }) : super(key: key); | 80 | + super.key, |
81 | + }); | ||
83 | @override | 82 | @override |
84 | Widget build(BuildContext context) { | 83 | Widget build(BuildContext context) { |
85 | return Padding( | 84 | return Padding( |
@@ -34,7 +34,7 @@ packages: | @@ -34,7 +34,7 @@ packages: | ||
34 | source: hosted | 34 | source: hosted |
35 | version: "1.1.1" | 35 | version: "1.1.1" |
36 | collection: | 36 | collection: |
37 | - dependency: transitive | 37 | + dependency: "direct main" |
38 | description: | 38 | description: |
39 | name: collection | 39 | name: collection |
40 | sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 | 40 | sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 |
@@ -84,10 +84,18 @@ packages: | @@ -84,10 +84,18 @@ packages: | ||
84 | dependency: "direct main" | 84 | dependency: "direct main" |
85 | description: | 85 | description: |
86 | name: go_router | 86 | name: go_router |
87 | - sha256: "2cb236ba3f923043fdbe14a6a3a796b8c250e85658e28caee3e86c0c275847e5" | 87 | + sha256: "5098760d7478aabfe682a462bf121d61bc5dbe5df5aac8dad733564a0aee33bc" |
88 | + url: "https://pub.dev" | ||
89 | + source: hosted | ||
90 | + version: "12.1.0" | ||
91 | + lints: | ||
92 | + dependency: "direct dev" | ||
93 | + description: | ||
94 | + name: lints | ||
95 | + sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 | ||
88 | url: "https://pub.dev" | 96 | url: "https://pub.dev" |
89 | source: hosted | 97 | source: hosted |
90 | - version: "8.2.0" | 98 | + version: "3.0.0" |
91 | logging: | 99 | logging: |
92 | dependency: transitive | 100 | dependency: transitive |
93 | description: | 101 | description: |
@@ -222,4 +230,4 @@ packages: | @@ -222,4 +230,4 @@ packages: | ||
222 | version: "0.1.4-beta" | 230 | version: "0.1.4-beta" |
223 | sdks: | 231 | sdks: |
224 | dart: ">=3.1.0-185.0.dev <4.0.0" | 232 | dart: ">=3.1.0-185.0.dev <4.0.0" |
225 | - flutter: ">=3.3.0" | 233 | + flutter: ">=3.7.0" |
@@ -10,15 +10,17 @@ dependencies: | @@ -10,15 +10,17 @@ dependencies: | ||
10 | flutter: | 10 | flutter: |
11 | sdk: flutter | 11 | sdk: flutter |
12 | equatable: ^2.0.5 | 12 | equatable: ^2.0.5 |
13 | - cupertino_icons: ^1.0.0 | 13 | + collection: |
14 | + cupertino_icons: ^1.0.6 | ||
14 | provider: ^6.0.5 | 15 | provider: ^6.0.5 |
15 | sheet: | 16 | sheet: |
16 | path: ../ | 17 | path: ../ |
17 | - go_router: ^8.0.5 | 18 | + go_router: ^12.1.0 |
18 | 19 | ||
19 | dev_dependencies: | 20 | dev_dependencies: |
20 | flutter_test: | 21 | flutter_test: |
21 | sdk: flutter | 22 | sdk: flutter |
23 | + lints: ^3.0.0 | ||
22 | 24 | ||
23 | flutter: | 25 | flutter: |
24 | uses-material-design: true | 26 | uses-material-design: true |
@@ -414,6 +414,16 @@ class SnapSheetPhysics extends ScrollPhysics with SheetPhysics { | @@ -414,6 +414,16 @@ class SnapSheetPhysics extends ScrollPhysics with SheetPhysics { | ||
414 | (old.relative != relative || !listEquals(old.stops, stops)); | 414 | (old.relative != relative || !listEquals(old.stops, stops)); |
415 | } | 415 | } |
416 | 416 | ||
417 | + @override | ||
418 | + double adjustPositionForNewDimensions( | ||
419 | + {required ScrollMetrics oldPosition, | ||
420 | + required ScrollMetrics newPosition, | ||
421 | + required bool isScrolling, | ||
422 | + required double velocity}) { | ||
423 | + final Tolerance tolerance = toleranceFor(newPosition); | ||
424 | + return _getTargetPixels(newPosition, tolerance, velocity); | ||
425 | + } | ||
426 | + | ||
417 | double _getTargetPixels( | 427 | double _getTargetPixels( |
418 | ScrollMetrics position, Tolerance tolerance, double velocity) { | 428 | ScrollMetrics position, Tolerance tolerance, double velocity) { |
419 | int page = _getPage(position) ?? 0; | 429 | int page = _getPage(position) ?? 0; |
@@ -8,6 +8,7 @@ import 'package:flutter/cupertino.dart'; | @@ -8,6 +8,7 @@ import 'package:flutter/cupertino.dart'; | ||
8 | import 'package:flutter/foundation.dart'; | 8 | import 'package:flutter/foundation.dart'; |
9 | import 'package:flutter/material.dart'; | 9 | import 'package:flutter/material.dart'; |
10 | import 'package:flutter/services.dart'; | 10 | import 'package:flutter/services.dart'; |
11 | +import 'package:meta/meta.dart'; | ||
11 | import 'package:sheet/route.dart'; | 12 | import 'package:sheet/route.dart'; |
12 | import 'package:sheet/sheet.dart'; | 13 | import 'package:sheet/sheet.dart'; |
13 | 14 | ||
@@ -219,7 +220,7 @@ class CupertinoSheetRoute<T> extends SheetRoute<T> { | @@ -219,7 +220,7 @@ class CupertinoSheetRoute<T> extends SheetRoute<T> { | ||
219 | } | 220 | } |
220 | 221 | ||
221 | /// Animation for previous route when a [CupertinoSheetRoute] enters/exits | 222 | /// Animation for previous route when a [CupertinoSheetRoute] enters/exits |
222 | -@visibleForTesting | 223 | +@internal |
223 | class CupertinoSheetBottomRouteTransition extends StatelessWidget { | 224 | class CupertinoSheetBottomRouteTransition extends StatelessWidget { |
224 | const CupertinoSheetBottomRouteTransition({ | 225 | const CupertinoSheetBottomRouteTransition({ |
225 | super.key, | 226 | super.key, |
@@ -349,7 +350,10 @@ class _PageBasedCupertinoSheetRoute<T> extends CupertinoSheetRoute<T> { | @@ -349,7 +350,10 @@ class _PageBasedCupertinoSheetRoute<T> extends CupertinoSheetRoute<T> { | ||
349 | super.maintainState, | 350 | super.maintainState, |
350 | }) : super( | 351 | }) : super( |
351 | settings: page, | 352 | settings: page, |
352 | - builder: (BuildContext context) => page.child, | 353 | + builder: (BuildContext context) { |
354 | + return (ModalRoute.of(context)!.settings as CupertinoSheetPage<T>) | ||
355 | + .child; | ||
356 | + }, | ||
353 | ); | 357 | ); |
354 | 358 | ||
355 | CupertinoSheetPage<T> get _page => settings as CupertinoSheetPage<T>; | 359 | CupertinoSheetPage<T> get _page => settings as CupertinoSheetPage<T>; |
@@ -343,6 +343,9 @@ class _PageBasedSheetRoute<T> extends SheetRoute<T> { | @@ -343,6 +343,9 @@ class _PageBasedSheetRoute<T> extends SheetRoute<T> { | ||
343 | SheetPage<T> get _page => settings as SheetPage<T>; | 343 | SheetPage<T> get _page => settings as SheetPage<T>; |
344 | 344 | ||
345 | @override | 345 | @override |
346 | + WidgetBuilder get builder => (context) => _page.child; | ||
347 | + | ||
348 | + @override | ||
346 | bool get maintainState => _page.maintainState; | 349 | bool get maintainState => _page.maintainState; |
347 | 350 | ||
348 | @override | 351 | @override |
@@ -4,7 +4,7 @@ import 'dart:math' as math; | @@ -4,7 +4,7 @@ import 'dart:math' as math; | ||
4 | import 'package:flutter/material.dart'; | 4 | import 'package:flutter/material.dart'; |
5 | import 'package:flutter/rendering.dart'; | 5 | import 'package:flutter/rendering.dart'; |
6 | import 'package:sheet/src/widgets/resizable_sheet.dart'; | 6 | import 'package:sheet/src/widgets/resizable_sheet.dart'; |
7 | -import 'package:sheet/src/widgets/scroll_to_top_status_handler.dart'; | 7 | +import 'package:sheet/src/widgets/status_bar_gesture_detector.dart'; |
8 | 8 | ||
9 | import '../sheet.dart'; | 9 | import '../sheet.dart'; |
10 | 10 | ||
@@ -261,7 +261,7 @@ class Sheet extends StatelessWidget { | @@ -261,7 +261,7 @@ class Sheet extends StatelessWidget { | ||
261 | scrollBehavior: SheetBehavior(), | 261 | scrollBehavior: SheetBehavior(), |
262 | viewportBuilder: (BuildContext context, ViewportOffset offset) { | 262 | viewportBuilder: (BuildContext context, ViewportOffset offset) { |
263 | return _DefaultSheetScrollController( | 263 | return _DefaultSheetScrollController( |
264 | - child: ScrollToTopStatusBarHandler( | 264 | + child: StatusBarGestureDetector.scrollToTop( |
265 | child: SheetViewport( | 265 | child: SheetViewport( |
266 | clipBehavior: Clip.antiAlias, | 266 | clipBehavior: Clip.antiAlias, |
267 | axisDirection: AxisDirection.down, | 267 | axisDirection: AxisDirection.down, |
@@ -894,8 +894,12 @@ class RenderSheetViewport extends RenderBox | @@ -894,8 +894,12 @@ class RenderSheetViewport extends RenderBox | ||
894 | } | 894 | } |
895 | 895 | ||
896 | @override | 896 | @override |
897 | - RevealedOffset getOffsetToReveal(RenderObject target, double alignment, | ||
898 | - {Rect? rect, Axis? axis}) { | 897 | + RevealedOffset getOffsetToReveal( |
898 | + RenderObject target, | ||
899 | + double alignment, { | ||
900 | + Axis? axis, | ||
901 | + Rect? rect, | ||
902 | + }) { | ||
899 | rect ??= target.paintBounds; | 903 | rect ??= target.paintBounds; |
900 | if (target is! RenderBox) { | 904 | if (target is! RenderBox) { |
901 | return RevealedOffset(offset: offset.pixels, rect: rect); | 905 | return RevealedOffset(offset: offset.pixels, rect: rect); |
@@ -14,7 +14,11 @@ typedef SheetControllerCallback = void Function(SheetController controller); | @@ -14,7 +14,11 @@ typedef SheetControllerCallback = void Function(SheetController controller); | ||
14 | /// | 14 | /// |
15 | /// | 15 | /// |
16 | class DefaultSheetController extends StatefulWidget { | 16 | class DefaultSheetController extends StatefulWidget { |
17 | - const DefaultSheetController({super.key, required this.child, this.onCreated}); | 17 | + const DefaultSheetController({ |
18 | + super.key, | ||
19 | + required this.child, | ||
20 | + this.onCreated, | ||
21 | + }); | ||
18 | 22 | ||
19 | final Widget child; | 23 | final Widget child; |
20 | 24 | ||
@@ -43,7 +47,9 @@ class _DefaultSheetControllerState extends State<DefaultSheetController> { | @@ -43,7 +47,9 @@ class _DefaultSheetControllerState extends State<DefaultSheetController> { | ||
43 | @override | 47 | @override |
44 | Widget build(BuildContext context) { | 48 | Widget build(BuildContext context) { |
45 | return _InheritedSheetController( | 49 | return _InheritedSheetController( |
46 | - child: widget.child, controller: controller); | 50 | + child: widget.child, |
51 | + controller: controller, | ||
52 | + ); | ||
47 | } | 53 | } |
48 | 54 | ||
49 | @override | 55 | @override |
@@ -54,8 +60,10 @@ class _DefaultSheetControllerState extends State<DefaultSheetController> { | @@ -54,8 +60,10 @@ class _DefaultSheetControllerState extends State<DefaultSheetController> { | ||
54 | } | 60 | } |
55 | 61 | ||
56 | class _InheritedSheetController extends InheritedWidget { | 62 | class _InheritedSheetController extends InheritedWidget { |
57 | - const _InheritedSheetController( | ||
58 | - {required super.child, required this.controller}); | 63 | + const _InheritedSheetController({ |
64 | + required super.child, | ||
65 | + required this.controller, | ||
66 | + }); | ||
59 | 67 | ||
60 | final SheetController controller; | 68 | final SheetController controller; |
61 | 69 |
1 | import 'package:flutter/cupertino.dart'; | 1 | import 'package:flutter/cupertino.dart'; |
2 | import 'package:flutter/rendering.dart'; | 2 | import 'package:flutter/rendering.dart'; |
3 | +import 'package:meta/meta.dart'; | ||
3 | 4 | ||
4 | /// A widget that add a min interaction zone where hitTestSelf is true | 5 | /// A widget that add a min interaction zone where hitTestSelf is true |
5 | /// This is rarely used by its own | 6 | /// This is rarely used by its own |
@@ -8,12 +9,13 @@ import 'package:flutter/rendering.dart'; | @@ -8,12 +9,13 @@ import 'package:flutter/rendering.dart'; | ||
8 | /// | 9 | /// |
9 | /// * [Sheet], that uses this widget that enables to drag closed/hidden | 10 | /// * [Sheet], that uses this widget that enables to drag closed/hidden |
10 | /// sheets | 11 | /// sheets |
12 | +@internal | ||
11 | class MinInteractionZone extends SingleChildRenderObjectWidget { | 13 | class MinInteractionZone extends SingleChildRenderObjectWidget { |
12 | const MinInteractionZone({ | 14 | const MinInteractionZone({ |
13 | required this.direction, | 15 | required this.direction, |
14 | required this.extent, | 16 | required this.extent, |
15 | - required Widget child, | ||
16 | - }) : super(child: child); | 17 | + super.child, |
18 | + }); | ||
17 | 19 | ||
18 | final AxisDirection direction; | 20 | final AxisDirection direction; |
19 | 21 | ||
@@ -41,7 +43,6 @@ class MinInteractionPaddingRenderBox extends RenderProxyBox { | @@ -41,7 +43,6 @@ class MinInteractionPaddingRenderBox extends RenderProxyBox { | ||
41 | AxisDirection _direction; | 43 | AxisDirection _direction; |
42 | AxisDirection get direction => _direction; | 44 | AxisDirection get direction => _direction; |
43 | set direction(AxisDirection value) { | 45 | set direction(AxisDirection value) { |
44 | - // ignore: always_put_control_body_on_new_line | ||
45 | if (value == _direction) return; | 46 | if (value == _direction) return; |
46 | _direction = value; | 47 | _direction = value; |
47 | } | 48 | } |
@@ -49,7 +50,6 @@ class MinInteractionPaddingRenderBox extends RenderProxyBox { | @@ -49,7 +50,6 @@ class MinInteractionPaddingRenderBox extends RenderProxyBox { | ||
49 | double _extent; | 50 | double _extent; |
50 | double get extent => _extent; | 51 | double get extent => _extent; |
51 | set extent(double value) { | 52 | set extent(double value) { |
52 | - // ignore: always_put_control_body_on_new_line | ||
53 | if (value == _extent) return; | 53 | if (value == _extent) return; |
54 | _extent = value; | 54 | _extent = value; |
55 | } | 55 | } |
1 | -import 'package:flutter/widgets.dart'; | 1 | +import 'package:flutter/material.dart'; |
2 | + | ||
3 | +typedef StatusBarGestureDetectorCallback = void Function(BuildContext context); | ||
2 | 4 | ||
3 | /// Widget that that will make the [scrollController] to scroll the top | 5 | /// Widget that that will make the [scrollController] to scroll the top |
4 | /// when tapped on the status bar | 6 | /// when tapped on the status bar |
5 | /// | 7 | /// |
6 | /// Extracted from [Scaffold] and used in [Sheet] | 8 | /// Extracted from [Scaffold] and used in [Sheet] |
7 | -class ScrollToTopStatusBarHandler extends StatefulWidget { | ||
8 | - const ScrollToTopStatusBarHandler({ | 9 | +class StatusBarGestureDetector extends StatefulWidget { |
10 | + const StatusBarGestureDetector({ | ||
9 | super.key, | 11 | super.key, |
10 | required this.child, | 12 | required this.child, |
13 | + required this.onTap, | ||
11 | }); | 14 | }); |
12 | 15 | ||
16 | + const StatusBarGestureDetector.scrollToTop({ | ||
17 | + super.key, | ||
18 | + required this.child, | ||
19 | + }) : onTap = _scrollToTopBarTap; | ||
20 | + | ||
21 | + static void _scrollToTopBarTap(BuildContext context) { | ||
22 | + final controller = PrimaryScrollController.maybeOf(context); | ||
23 | + if (controller != null && controller.hasClients) { | ||
24 | + controller.animateTo( | ||
25 | + 0.0, | ||
26 | + duration: const Duration(milliseconds: 1000), | ||
27 | + curve: Curves.easeOutCirc, | ||
28 | + ); | ||
29 | + } | ||
30 | + } | ||
31 | + | ||
13 | final Widget child; | 32 | final Widget child; |
14 | 33 | ||
34 | + final StatusBarGestureDetectorCallback onTap; | ||
35 | + | ||
15 | @override | 36 | @override |
16 | - ScrollToTopStatusBarState createState() => ScrollToTopStatusBarState(); | 37 | + State<StatusBarGestureDetector> createState() => |
38 | + _StatusBarGestureDetectorState(); | ||
17 | } | 39 | } |
18 | 40 | ||
19 | -class ScrollToTopStatusBarState extends State<ScrollToTopStatusBarHandler> { | 41 | +class _StatusBarGestureDetectorState extends State<StatusBarGestureDetector> { |
42 | + final OverlayPortalController controller = OverlayPortalController(); | ||
43 | + | ||
20 | @override | 44 | @override |
21 | void initState() { | 45 | void initState() { |
46 | + controller.show(); | ||
22 | super.initState(); | 47 | super.initState(); |
23 | } | 48 | } |
24 | 49 | ||
25 | @override | 50 | @override |
26 | Widget build(BuildContext context) { | 51 | Widget build(BuildContext context) { |
27 | - return Stack( | ||
28 | - fit: StackFit.expand, | ||
29 | - children: <Widget>[ | ||
30 | - widget.child, | ||
31 | - Positioned( | ||
32 | - top: 0, | ||
33 | - left: 0, | ||
34 | - right: 0, | ||
35 | - height: MediaQuery.maybeOf(context)?.padding.top ?? 0, | ||
36 | - child: Builder( | ||
37 | - builder: (BuildContext context) { | ||
38 | - return GestureDetector( | ||
39 | - behavior: HitTestBehavior.opaque, | ||
40 | - onTap: () => _handleStatusBarTap(context), | ||
41 | - // iOS accessibility automatically adds scroll-to-top to the clock in the status bar | ||
42 | - excludeFromSemantics: true, | ||
43 | - ); | ||
44 | - }, | 52 | + final view = View.of(context); |
53 | + return OverlayPortal.targetsRootOverlay( | ||
54 | + controller: controller, | ||
55 | + overlayChildBuilder: (context) { | ||
56 | + return Align( | ||
57 | + alignment: Alignment.topCenter, | ||
58 | + child: SizedBox( | ||
59 | + height: view.padding.top / view.devicePixelRatio, | ||
60 | + width: double.infinity, | ||
61 | + child: GestureDetector( | ||
62 | + behavior: HitTestBehavior.opaque, | ||
63 | + onTap: () => widget.onTap(context), | ||
64 | + // iOS accessibility automatically adds scroll-to-top to the clock in the status bar | ||
65 | + excludeFromSemantics: true, | ||
66 | + ), | ||
45 | ), | 67 | ), |
46 | - ), | ||
47 | - ], | 68 | + ); |
69 | + }, | ||
70 | + child: widget.child, | ||
48 | ); | 71 | ); |
49 | } | 72 | } |
50 | - | ||
51 | - void _handleStatusBarTap(BuildContext context) { | ||
52 | - final ScrollController? controller = | ||
53 | - PrimaryScrollController.maybeOf(context); | ||
54 | - if (controller != null && controller.hasClients) { | ||
55 | - controller.animateTo( | ||
56 | - 0.0, | ||
57 | - duration: const Duration(milliseconds: 300), | ||
58 | - curve: Curves.linear, // TODO(ianh): Use a more appropriate curve. | ||
59 | - ); | ||
60 | - } | ||
61 | - } | ||
62 | } | 73 | } |
@@ -84,7 +84,7 @@ packages: | @@ -84,7 +84,7 @@ packages: | ||
84 | source: hosted | 84 | source: hosted |
85 | version: "0.5.0" | 85 | version: "0.5.0" |
86 | meta: | 86 | meta: |
87 | - dependency: transitive | 87 | + dependency: "direct main" |
88 | description: | 88 | description: |
89 | name: meta | 89 | name: meta |
90 | sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" | 90 | sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" |
@@ -4,12 +4,13 @@ version: 1.0.0-pre | @@ -4,12 +4,13 @@ version: 1.0.0-pre | ||
4 | homepage: https://github.com/jamesblasco/modal_bottom_sheet | 4 | homepage: https://github.com/jamesblasco/modal_bottom_sheet |
5 | 5 | ||
6 | environment: | 6 | environment: |
7 | - sdk: ">=2.17.0 <3.0.0" | 7 | + sdk: ">=3.0.0 <4.0.0" |
8 | 8 | ||
9 | dependencies: | 9 | dependencies: |
10 | flutter: | 10 | flutter: |
11 | sdk: flutter | 11 | sdk: flutter |
12 | - | 12 | + meta: ^1.9.1 |
13 | + | ||
13 | dev_dependencies: | 14 | dev_dependencies: |
14 | flutter_test: | 15 | flutter_test: |
15 | sdk: flutter | 16 | sdk: flutter |
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | // Use of this source code is governed by a BSD-style license that can be | 2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. | 3 | // found in the LICENSE file. |
4 | 4 | ||
5 | -import 'package:flutter/widgets.dart'; | 5 | +import 'package:flutter/material.dart'; |
6 | import 'package:flutter_test/flutter_test.dart'; | 6 | import 'package:flutter_test/flutter_test.dart'; |
7 | import 'package:sheet/sheet.dart'; | 7 | import 'package:sheet/sheet.dart'; |
8 | 8 | ||
@@ -54,9 +54,8 @@ void main() { | @@ -54,9 +54,8 @@ void main() { | ||
54 | // ScrollController's ScrollPosition to be rebuilt. | 54 | // ScrollController's ScrollPosition to be rebuilt. |
55 | 55 | ||
56 | Widget buildFrame(SheetPhysics? physics) { | 56 | Widget buildFrame(SheetPhysics? physics) { |
57 | - return Directionality( | ||
58 | - textDirection: TextDirection.ltr, | ||
59 | - child: Sheet( | 57 | + return MaterialApp( |
58 | + home: Sheet( | ||
60 | controller: controller, | 59 | controller: controller, |
61 | physics: physics, | 60 | physics: physics, |
62 | child: ScrollPositionListener( | 61 | child: ScrollPositionListener( |
1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
2 | import 'package:flutter_test/flutter_test.dart'; | 2 | import 'package:flutter_test/flutter_test.dart'; |
3 | -import 'package:sheet/src/widgets/scroll_to_top_status_handler.dart'; | 3 | +import 'package:sheet/src/widgets/status_bar_gesture_detector.dart'; |
4 | 4 | ||
5 | void main() { | 5 | void main() { |
6 | - testWidgets('Tap status bar scrolls primary scroll controller', | ||
7 | - (WidgetTester tester) async { | ||
8 | - final ScrollController controller = ScrollController(); | ||
9 | - await tester.pumpWidget(MaterialApp( | ||
10 | - builder: (BuildContext context, Widget? child) { | ||
11 | - return MediaQuery( | ||
12 | - data: MediaQuery.of(context).copyWith( | ||
13 | - padding: const EdgeInsets.all(20), | ||
14 | - ), | ||
15 | - child: child!, | ||
16 | - ); | ||
17 | - }, | ||
18 | - home: PrimaryScrollController( | ||
19 | - controller: controller, | ||
20 | - child: ScrollToTopStatusBarHandler( | ||
21 | - child: Material( | ||
22 | - child: ListView.builder( | ||
23 | - controller: controller, | ||
24 | - itemBuilder: (BuildContext context, int index) { | ||
25 | - return ListTile(title: Text('Text $index')); | ||
26 | - }, | 6 | + group('StatusBarGestureDetector', () { |
7 | + testWidgets('Tap status bar calls onTap callback', | ||
8 | + (WidgetTester tester) async { | ||
9 | + tester.view.padding = FakeViewPadding(top: 20); | ||
10 | + bool called = false; | ||
11 | + await tester.pumpWidget(MaterialApp( | ||
12 | + home: StatusBarGestureDetector( | ||
13 | + onTap: (_) => called = true, | ||
14 | + child: Container(), | ||
15 | + ), | ||
16 | + )); | ||
17 | + await tester.tapAt(Offset.zero); | ||
18 | + await tester.pumpAndSettle(); | ||
19 | + expect(called, isTrue); | ||
20 | + }); | ||
21 | + testWidgets('Tap status bar scrolls primary scroll controller', | ||
22 | + (WidgetTester tester) async { | ||
23 | + final ScrollController controller = ScrollController(); | ||
24 | + tester.view.padding = FakeViewPadding(top: 20); | ||
25 | + await tester.pumpWidget(MaterialApp( | ||
26 | + home: PrimaryScrollController( | ||
27 | + controller: controller, | ||
28 | + child: StatusBarGestureDetector.scrollToTop( | ||
29 | + child: Material( | ||
30 | + child: ListView.builder( | ||
31 | + controller: controller, | ||
32 | + itemBuilder: (BuildContext context, int index) { | ||
33 | + return ListTile(title: Text('Text $index')); | ||
34 | + }, | ||
35 | + ), | ||
27 | ), | 36 | ), |
28 | ), | 37 | ), |
29 | ), | 38 | ), |
30 | - ), | ||
31 | - )); | ||
32 | - controller.jumpTo(200); | ||
33 | - await tester.pump(); | ||
34 | - await tester.tapAt(Offset.zero); | ||
35 | - await tester.pumpAndSettle(); | ||
36 | - expect(controller.position.pixels, isZero); | 39 | + )); |
40 | + controller.jumpTo(200); | ||
41 | + await tester.pump(); | ||
42 | + await tester.tapAt(Offset.zero); | ||
43 | + await tester.pumpAndSettle(); | ||
44 | + expect(controller.position.pixels, isZero); | ||
45 | + }); | ||
37 | }); | 46 | }); |
38 | } | 47 | } |
-
Please register or login to post a comment