Showing
19 changed files
with
203 additions
and
171 deletions
@@ -53,8 +53,8 @@ class CupertinoSharePage extends StatelessWidget { | @@ -53,8 +53,8 @@ class CupertinoSharePage extends StatelessWidget { | ||
53 | expand: true, | 53 | expand: true, |
54 | context: context, | 54 | context: context, |
55 | backgroundColor: Colors.transparent, | 55 | backgroundColor: Colors.transparent, |
56 | - builder: (context, scrollController) => | ||
57 | - PhotoShareBottomSheet(scrollController: scrollController), | 56 | + builder: (context) => |
57 | + PhotoShareBottomSheet(), | ||
58 | ); | 58 | ); |
59 | }, | 59 | }, |
60 | ), | 60 | ), |
@@ -73,9 +73,9 @@ class CupertinoSharePage extends StatelessWidget { | @@ -73,9 +73,9 @@ class CupertinoSharePage extends StatelessWidget { | ||
73 | } | 73 | } |
74 | 74 | ||
75 | class PhotoShareBottomSheet extends StatelessWidget { | 75 | class PhotoShareBottomSheet extends StatelessWidget { |
76 | - final ScrollController scrollController; | ||
77 | 76 | ||
78 | - const PhotoShareBottomSheet({Key key, this.scrollController}) | 77 | + |
78 | + const PhotoShareBottomSheet({Key key}) | ||
79 | : super(key: key); | 79 | : super(key: key); |
80 | 80 | ||
81 | @override | 81 | @override |
@@ -92,7 +92,7 @@ class PhotoShareBottomSheet extends StatelessWidget { | @@ -92,7 +92,7 @@ class PhotoShareBottomSheet extends StatelessWidget { | ||
92 | appBar: appBar(context), | 92 | appBar: appBar(context), |
93 | body: CustomScrollView( | 93 | body: CustomScrollView( |
94 | physics: ClampingScrollPhysics(), | 94 | physics: ClampingScrollPhysics(), |
95 | - controller: scrollController, | 95 | + controller: ModalScrollController.of(context), |
96 | slivers: <Widget>[ | 96 | slivers: <Widget>[ |
97 | SliverSafeArea( | 97 | SliverSafeArea( |
98 | bottom: false, | 98 | bottom: false, |
@@ -51,11 +51,9 @@ class MyApp extends StatelessWidget { | @@ -51,11 +51,9 @@ class MyApp extends StatelessWidget { | ||
51 | expand: true, | 51 | expand: true, |
52 | context: context, | 52 | context: context, |
53 | backgroundColor: Colors.transparent, | 53 | backgroundColor: Colors.transparent, |
54 | - builder: (context, scrollController) => | ||
55 | - Stack( | 54 | + builder: (context) => Stack( |
56 | children: <Widget>[ | 55 | children: <Widget>[ |
57 | - ModalWithScroll( | ||
58 | - scrollController: scrollController), | 56 | + ModalWithScroll(), |
59 | Positioned( | 57 | Positioned( |
60 | height: 40, | 58 | height: 40, |
61 | left: 40, | 59 | left: 40, |
@@ -131,8 +129,7 @@ class _MyHomePageState extends State<MyHomePage> { | @@ -131,8 +129,7 @@ class _MyHomePageState extends State<MyHomePage> { | ||
131 | expand: false, | 129 | expand: false, |
132 | context: context, | 130 | context: context, |
133 | backgroundColor: Colors.transparent, | 131 | backgroundColor: Colors.transparent, |
134 | - builder: (context, scrollController) => | ||
135 | - ModalFit(scrollController: scrollController), | 132 | + builder: (context) => ModalFit(), |
136 | )), | 133 | )), |
137 | ListTile( | 134 | ListTile( |
138 | title: Text('Bar Modal'), | 135 | title: Text('Bar Modal'), |
@@ -140,9 +137,7 @@ class _MyHomePageState extends State<MyHomePage> { | @@ -140,9 +137,7 @@ class _MyHomePageState extends State<MyHomePage> { | ||
140 | expand: true, | 137 | expand: true, |
141 | context: context, | 138 | context: context, |
142 | backgroundColor: Colors.transparent, | 139 | backgroundColor: Colors.transparent, |
143 | - builder: (context, scrollController) => | ||
144 | - ModalInsideModal( | ||
145 | - scrollController: scrollController), | 140 | + builder: (context) => ModalInsideModal(), |
146 | )), | 141 | )), |
147 | ListTile( | 142 | ListTile( |
148 | title: Text('Avatar Modal'), | 143 | title: Text('Avatar Modal'), |
@@ -150,16 +145,13 @@ class _MyHomePageState extends State<MyHomePage> { | @@ -150,16 +145,13 @@ class _MyHomePageState extends State<MyHomePage> { | ||
150 | expand: true, | 145 | expand: true, |
151 | context: context, | 146 | context: context, |
152 | backgroundColor: Colors.transparent, | 147 | backgroundColor: Colors.transparent, |
153 | - builder: (context, scrollController) => | ||
154 | - ModalInsideModal( | ||
155 | - scrollController: scrollController), | 148 | + builder: (context) => ModalInsideModal(), |
156 | )), | 149 | )), |
157 | ListTile( | 150 | ListTile( |
158 | title: Text('Float Modal'), | 151 | title: Text('Float Modal'), |
159 | onTap: () => showFloatingModalBottomSheet( | 152 | onTap: () => showFloatingModalBottomSheet( |
160 | context: context, | 153 | context: context, |
161 | - builder: (context, scrollController) => | ||
162 | - ModalFit(scrollController: scrollController), | 154 | + builder: (context) => ModalFit(), |
163 | )), | 155 | )), |
164 | ListTile( | 156 | ListTile( |
165 | title: Text('Cupertino Modal fit'), | 157 | title: Text('Cupertino Modal fit'), |
@@ -167,8 +159,7 @@ class _MyHomePageState extends State<MyHomePage> { | @@ -167,8 +159,7 @@ class _MyHomePageState extends State<MyHomePage> { | ||
167 | expand: false, | 159 | expand: false, |
168 | context: context, | 160 | context: context, |
169 | backgroundColor: Colors.transparent, | 161 | backgroundColor: Colors.transparent, |
170 | - builder: (context, scrollController) => | ||
171 | - ModalFit(scrollController: scrollController), | 162 | + builder: (context) => ModalFit(), |
172 | )), | 163 | )), |
173 | section('COMPLEX CASES'), | 164 | section('COMPLEX CASES'), |
174 | ListTile( | 165 | ListTile( |
@@ -177,8 +168,7 @@ class _MyHomePageState extends State<MyHomePage> { | @@ -177,8 +168,7 @@ class _MyHomePageState extends State<MyHomePage> { | ||
177 | expand: true, | 168 | expand: true, |
178 | context: context, | 169 | context: context, |
179 | backgroundColor: Colors.transparent, | 170 | backgroundColor: Colors.transparent, |
180 | - builder: (context, scrollController) => | ||
181 | - ModalFit(scrollController: scrollController), | 171 | + builder: (context) => ModalFit(), |
182 | )), | 172 | )), |
183 | ListTile( | 173 | ListTile( |
184 | title: Text('Reverse list'), | 174 | title: Text('Reverse list'), |
@@ -186,10 +176,8 @@ class _MyHomePageState extends State<MyHomePage> { | @@ -186,10 +176,8 @@ class _MyHomePageState extends State<MyHomePage> { | ||
186 | expand: true, | 176 | expand: true, |
187 | context: context, | 177 | context: context, |
188 | backgroundColor: Colors.transparent, | 178 | backgroundColor: Colors.transparent, |
189 | - builder: (context, scrollController) => | ||
190 | - ModalInsideModal( | ||
191 | - scrollController: scrollController, | ||
192 | - reverse: true), | 179 | + builder: (context) => |
180 | + ModalInsideModal(reverse: true), | ||
193 | )), | 181 | )), |
194 | ListTile( | 182 | ListTile( |
195 | title: Text('Cupertino Modal inside modal'), | 183 | title: Text('Cupertino Modal inside modal'), |
@@ -197,9 +185,7 @@ class _MyHomePageState extends State<MyHomePage> { | @@ -197,9 +185,7 @@ class _MyHomePageState extends State<MyHomePage> { | ||
197 | expand: true, | 185 | expand: true, |
198 | context: context, | 186 | context: context, |
199 | backgroundColor: Colors.transparent, | 187 | backgroundColor: Colors.transparent, |
200 | - builder: (context, scrollController) => | ||
201 | - ModalInsideModal( | ||
202 | - scrollController: scrollController), | 188 | + builder: (context) => ModalInsideModal(), |
203 | )), | 189 | )), |
204 | ListTile( | 190 | ListTile( |
205 | title: Text('Cupertino Modal with inside navigation'), | 191 | title: Text('Cupertino Modal with inside navigation'), |
@@ -207,9 +193,7 @@ class _MyHomePageState extends State<MyHomePage> { | @@ -207,9 +193,7 @@ class _MyHomePageState extends State<MyHomePage> { | ||
207 | expand: true, | 193 | expand: true, |
208 | context: context, | 194 | context: context, |
209 | backgroundColor: Colors.transparent, | 195 | backgroundColor: Colors.transparent, |
210 | - builder: (context, scrollController) => | ||
211 | - ModalWithNavigator( | ||
212 | - scrollController: scrollController), | 196 | + builder: (context) => ModalWithNavigator(), |
213 | )), | 197 | )), |
214 | ListTile( | 198 | ListTile( |
215 | title: | 199 | title: |
@@ -218,9 +202,8 @@ class _MyHomePageState extends State<MyHomePage> { | @@ -218,9 +202,8 @@ class _MyHomePageState extends State<MyHomePage> { | ||
218 | expand: true, | 202 | expand: true, |
219 | context: context, | 203 | context: context, |
220 | backgroundColor: Colors.transparent, | 204 | backgroundColor: Colors.transparent, |
221 | - builder: (context, scrollController) => | ||
222 | - ComplexModal( | ||
223 | - scrollController: scrollController), | 205 | + builder: (context) => |
206 | + ComplexModal(), | ||
224 | )), | 207 | )), |
225 | ListTile( | 208 | ListTile( |
226 | title: Text('Modal with WillPopScope'), | 209 | title: Text('Modal with WillPopScope'), |
@@ -228,18 +211,16 @@ class _MyHomePageState extends State<MyHomePage> { | @@ -228,18 +211,16 @@ class _MyHomePageState extends State<MyHomePage> { | ||
228 | expand: true, | 211 | expand: true, |
229 | context: context, | 212 | context: context, |
230 | backgroundColor: Colors.transparent, | 213 | backgroundColor: Colors.transparent, |
231 | - builder: (context, scrollController) => | ||
232 | - ModalWillScope( | ||
233 | - scrollController: scrollController), | 214 | + builder: (context) => |
215 | + ModalWillScope(), | ||
234 | )), | 216 | )), |
235 | ListTile( | 217 | ListTile( |
236 | title: Text('Modal with Nested Scroll'), | 218 | title: Text('Modal with Nested Scroll'), |
237 | onTap: () => showCupertinoModalBottomSheet( | 219 | onTap: () => showCupertinoModalBottomSheet( |
238 | expand: true, | 220 | expand: true, |
239 | context: context, | 221 | context: context, |
240 | - builder: (context, scrollController) => | ||
241 | - NestedScrollModal( | ||
242 | - scrollController: scrollController), | 222 | + builder: (context) => |
223 | + NestedScrollModal(), | ||
243 | )), | 224 | )), |
244 | ListTile( | 225 | ListTile( |
245 | title: Text('Modal with PageView'), | 226 | title: Text('Modal with PageView'), |
@@ -69,7 +69,7 @@ class AvatarBottomSheet extends StatelessWidget { | @@ -69,7 +69,7 @@ class AvatarBottomSheet extends StatelessWidget { | ||
69 | 69 | ||
70 | Future<T> showAvatarModalBottomSheet<T>({ | 70 | Future<T> showAvatarModalBottomSheet<T>({ |
71 | @required BuildContext context, | 71 | @required BuildContext context, |
72 | - @required ScrollWidgetBuilder builder, | 72 | + @required WidgetBuilder builder, |
73 | Color backgroundColor, | 73 | Color backgroundColor, |
74 | double elevation, | 74 | double elevation, |
75 | ShapeBorder shape, | 75 | ShapeBorder shape, |
@@ -27,7 +27,7 @@ class FloatingModal extends StatelessWidget { | @@ -27,7 +27,7 @@ class FloatingModal extends StatelessWidget { | ||
27 | 27 | ||
28 | Future<T> showFloatingModalBottomSheet<T>({ | 28 | Future<T> showFloatingModalBottomSheet<T>({ |
29 | @required BuildContext context, | 29 | @required BuildContext context, |
30 | - @required ScrollWidgetBuilder builder, | 30 | + @required WidgetBuilder builder, |
31 | Color backgroundColor, | 31 | Color backgroundColor, |
32 | }) async { | 32 | }) async { |
33 | final result = await showCustomModalBottomSheet( | 33 | final result = await showCustomModalBottomSheet( |
1 | import 'package:flutter/cupertino.dart'; | 1 | import 'package:flutter/cupertino.dart'; |
2 | import 'package:flutter/material.dart'; | 2 | import 'package:flutter/material.dart'; |
3 | +import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; | ||
3 | 4 | ||
4 | class ComplexModal extends StatelessWidget { | 5 | class ComplexModal extends StatelessWidget { |
5 | - final ScrollController scrollController; | ||
6 | - | ||
7 | - const ComplexModal({Key key, this.scrollController}) : super(key: key); | 6 | + const ComplexModal({Key key}) : super(key: key); |
8 | 7 | ||
9 | @override | 8 | @override |
10 | Widget build(BuildContext context) { | 9 | Widget build(BuildContext context) { |
@@ -46,7 +45,7 @@ class ComplexModal extends StatelessWidget { | @@ -46,7 +45,7 @@ class ComplexModal extends StatelessWidget { | ||
46 | bottom: false, | 45 | bottom: false, |
47 | child: ListView( | 46 | child: ListView( |
48 | shrinkWrap: true, | 47 | shrinkWrap: true, |
49 | - controller: scrollController, | 48 | + controller: ModalScrollController.of(context), |
50 | children: ListTile.divideTiles( | 49 | children: ListTile.divideTiles( |
51 | context: context, | 50 | context: context, |
52 | tiles: List.generate( | 51 | tiles: List.generate( |
@@ -2,9 +2,9 @@ import 'package:flutter/cupertino.dart'; | @@ -2,9 +2,9 @@ import 'package:flutter/cupertino.dart'; | ||
2 | import 'package:flutter/material.dart'; | 2 | import 'package:flutter/material.dart'; |
3 | 3 | ||
4 | class ModalFit extends StatelessWidget { | 4 | class ModalFit extends StatelessWidget { |
5 | - final ScrollController scrollController; | ||
6 | 5 | ||
7 | - const ModalFit({Key key, this.scrollController}) : super(key: key); | 6 | + |
7 | + const ModalFit({Key key}) : super(key: key); | ||
8 | 8 | ||
9 | @override | 9 | @override |
10 | Widget build(BuildContext context) { | 10 | Widget build(BuildContext context) { |
@@ -3,11 +3,9 @@ import 'package:flutter/material.dart'; | @@ -3,11 +3,9 @@ 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 ModalInsideModal extends StatelessWidget { | 5 | class ModalInsideModal extends StatelessWidget { |
6 | - final ScrollController scrollController; | ||
7 | final bool reverse; | 6 | final bool reverse; |
8 | 7 | ||
9 | - const ModalInsideModal({Key key, this.scrollController, this.reverse = false}) | ||
10 | - : super(key: key); | 8 | + const ModalInsideModal({Key key, this.reverse = false}) : super(key: key); |
11 | 9 | ||
12 | @override | 10 | @override |
13 | Widget build(BuildContext context) { | 11 | Widget build(BuildContext context) { |
@@ -20,7 +18,7 @@ class ModalInsideModal extends StatelessWidget { | @@ -20,7 +18,7 @@ class ModalInsideModal extends StatelessWidget { | ||
20 | child: ListView( | 18 | child: ListView( |
21 | reverse: reverse, | 19 | reverse: reverse, |
22 | shrinkWrap: true, | 20 | shrinkWrap: true, |
23 | - controller: scrollController, | 21 | + controller: ModalScrollController.of(context), |
24 | physics: ClampingScrollPhysics(), | 22 | physics: ClampingScrollPhysics(), |
25 | children: ListTile.divideTiles( | 23 | children: ListTile.divideTiles( |
26 | context: context, | 24 | context: context, |
@@ -33,10 +31,8 @@ class ModalInsideModal extends StatelessWidget { | @@ -33,10 +31,8 @@ class ModalInsideModal extends StatelessWidget { | ||
33 | isDismissible: false, | 31 | isDismissible: false, |
34 | context: context, | 32 | context: context, |
35 | backgroundColor: Colors.transparent, | 33 | backgroundColor: Colors.transparent, |
36 | - builder: (context, scrollController) => | ||
37 | - ModalInsideModal( | ||
38 | - scrollController: scrollController, | ||
39 | - reverse: reverse), | 34 | + builder: (context) => |
35 | + ModalInsideModal(reverse: reverse), | ||
40 | )), | 36 | )), |
41 | )).toList(), | 37 | )).toList(), |
42 | ), | 38 | ), |
@@ -2,9 +2,9 @@ import 'package:flutter/cupertino.dart'; | @@ -2,9 +2,9 @@ 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 | - final ScrollController scrollController; | ||
6 | 5 | ||
7 | - const ModalWillScope({Key key, this.scrollController}) : super(key: key); | 6 | + |
7 | + const ModalWillScope({Key key}) : super(key: key); | ||
8 | 8 | ||
9 | @override | 9 | @override |
10 | Widget build(BuildContext context) { | 10 | Widget build(BuildContext context) { |
1 | import 'package:flutter/cupertino.dart'; | 1 | import 'package:flutter/cupertino.dart'; |
2 | import 'package:flutter/material.dart'; | 2 | import 'package:flutter/material.dart'; |
3 | +import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; | ||
3 | 4 | ||
4 | class ModalWithNavigator extends StatelessWidget { | 5 | class ModalWithNavigator extends StatelessWidget { |
5 | - final ScrollController scrollController; | ||
6 | 6 | ||
7 | - const ModalWithNavigator({Key key, this.scrollController}) : super(key: key); | 7 | + |
8 | + const ModalWithNavigator({Key key}) : super(key: key); | ||
8 | 9 | ||
9 | @override | 10 | @override |
10 | Widget build(BuildContext context) { | 11 | Widget build(BuildContext context) { |
@@ -20,7 +21,7 @@ class ModalWithNavigator extends StatelessWidget { | @@ -20,7 +21,7 @@ class ModalWithNavigator extends StatelessWidget { | ||
20 | bottom: false, | 21 | bottom: false, |
21 | child: ListView( | 22 | child: ListView( |
22 | shrinkWrap: true, | 23 | shrinkWrap: true, |
23 | - controller: scrollController, | 24 | + controller: ModalScrollController.of(context), |
24 | children: ListTile.divideTiles( | 25 | children: ListTile.divideTiles( |
25 | context: context, | 26 | context: context, |
26 | tiles: List.generate( | 27 | tiles: List.generate( |
1 | import 'package:flutter/cupertino.dart'; | 1 | import 'package:flutter/cupertino.dart'; |
2 | import 'package:flutter/material.dart'; | 2 | import 'package:flutter/material.dart'; |
3 | +import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; | ||
3 | 4 | ||
4 | class NestedScrollModal extends StatelessWidget { | 5 | class NestedScrollModal extends StatelessWidget { |
5 | - final ScrollController scrollController; | 6 | + const NestedScrollModal({Key key}) : super(key: key); |
6 | 7 | ||
7 | - const NestedScrollModal({Key key, this.scrollController}) : super(key: key); | ||
8 | 8 | ||
9 | @override | 9 | @override |
10 | Widget build(BuildContext context) { | 10 | Widget build(BuildContext context) { |
@@ -23,7 +23,7 @@ class NestedScrollModal extends StatelessWidget { | @@ -23,7 +23,7 @@ class NestedScrollModal extends StatelessWidget { | ||
23 | ]; | 23 | ]; |
24 | }, | 24 | }, |
25 | body: ListView.builder( | 25 | body: ListView.builder( |
26 | - controller: scrollController, | 26 | + controller: ModalScrollController.of(context), |
27 | itemBuilder: (context, index) { | 27 | itemBuilder: (context, index) { |
28 | return Container( | 28 | return Container( |
29 | height: 100, | 29 | height: 100, |
1 | import 'package:flutter/cupertino.dart'; | 1 | import 'package:flutter/cupertino.dart'; |
2 | import 'package:flutter/material.dart'; | 2 | import 'package:flutter/material.dart'; |
3 | +import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; | ||
3 | 4 | ||
4 | class ModalWithScroll extends StatelessWidget { | 5 | class ModalWithScroll extends StatelessWidget { |
5 | - final ScrollController scrollController; | ||
6 | - | ||
7 | - const ModalWithScroll({Key key, this.scrollController}) : super(key: key); | 6 | + const ModalWithScroll({Key key}) : super(key: key); |
8 | 7 | ||
9 | @override | 8 | @override |
10 | Widget build(BuildContext context) { | 9 | Widget build(BuildContext context) { |
10 | + | ||
11 | return Material( | 11 | return Material( |
12 | child: CupertinoPageScaffold( | 12 | child: CupertinoPageScaffold( |
13 | navigationBar: CupertinoNavigationBar( | 13 | navigationBar: CupertinoNavigationBar( |
@@ -16,7 +16,7 @@ class ModalWithScroll extends StatelessWidget { | @@ -16,7 +16,7 @@ class ModalWithScroll extends StatelessWidget { | ||
16 | bottom: false, | 16 | bottom: false, |
17 | child: ListView( | 17 | child: ListView( |
18 | shrinkWrap: true, | 18 | shrinkWrap: true, |
19 | - controller: scrollController, | 19 | + controller: ModalScrollController.of(context), |
20 | children: ListTile.divideTiles( | 20 | children: ListTile.divideTiles( |
21 | context: context, | 21 | context: context, |
22 | tiles: List.generate( | 22 | tiles: List.generate( |
@@ -4,3 +4,4 @@ export 'src/material_with_modal_page_route.dart'; | @@ -4,3 +4,4 @@ export 'src/material_with_modal_page_route.dart'; | ||
4 | export 'src/bottom_sheets/cupertino_bottom_sheet.dart'; | 4 | export 'src/bottom_sheets/cupertino_bottom_sheet.dart'; |
5 | export 'src/bottom_sheets/material_bottom_sheet.dart'; | 5 | export 'src/bottom_sheets/material_bottom_sheet.dart'; |
6 | export 'src/bottom_sheets/bar_bottom_sheet.dart'; | 6 | export 'src/bottom_sheets/bar_bottom_sheet.dart'; |
7 | +export 'src/utils/modal_scroll_controller.dart'; |
@@ -9,7 +9,7 @@ import 'package:flutter/gestures.dart'; | @@ -9,7 +9,7 @@ import 'package:flutter/gestures.dart'; | ||
9 | import 'package:flutter/material.dart'; | 9 | import 'package:flutter/material.dart'; |
10 | import 'package:flutter/scheduler.dart'; | 10 | import 'package:flutter/scheduler.dart'; |
11 | import 'package:flutter/widgets.dart'; | 11 | import 'package:flutter/widgets.dart'; |
12 | -import 'package:modal_bottom_sheet/src/utils/primary_scroll_status_bar.dart'; | 12 | +import 'package:modal_bottom_sheet/src/utils/scroll_to_top_status_bar.dart'; |
13 | 13 | ||
14 | import 'package:modal_bottom_sheet/src/utils/bottom_sheet_suspended_curve.dart'; | 14 | import 'package:modal_bottom_sheet/src/utils/bottom_sheet_suspended_curve.dart'; |
15 | 15 | ||
@@ -20,9 +20,6 @@ const double _minFlingVelocity = 500.0; | @@ -20,9 +20,6 @@ const double _minFlingVelocity = 500.0; | ||
20 | const double _closeProgressThreshold = 0.6; | 20 | const double _closeProgressThreshold = 0.6; |
21 | const double _willPopThreshold = 0.8; | 21 | const double _willPopThreshold = 0.8; |
22 | 22 | ||
23 | -typedef ScrollWidgetBuilder = Widget Function( | ||
24 | - BuildContext context, ScrollController controller); | ||
25 | - | ||
26 | typedef WidgetWithChildBuilder = Widget Function( | 23 | typedef WidgetWithChildBuilder = Widget Function( |
27 | BuildContext context, Animation<double> animation, Widget child); | 24 | BuildContext context, Animation<double> animation, Widget child); |
28 | 25 | ||
@@ -51,10 +48,10 @@ class ModalBottomSheet extends StatefulWidget { | @@ -51,10 +48,10 @@ class ModalBottomSheet extends StatefulWidget { | ||
51 | this.scrollController, | 48 | this.scrollController, |
52 | this.expanded, | 49 | this.expanded, |
53 | @required this.onClosing, | 50 | @required this.onClosing, |
54 | - @required this.builder, | 51 | + @required this.child, |
55 | }) : assert(enableDrag != null), | 52 | }) : assert(enableDrag != null), |
56 | assert(onClosing != null), | 53 | assert(onClosing != null), |
57 | - assert(builder != null), | 54 | + assert(child != null), |
58 | super(key: key); | 55 | super(key: key); |
59 | 56 | ||
60 | /// The closeProgressThreshold parameter | 57 | /// The closeProgressThreshold parameter |
@@ -100,7 +97,7 @@ class ModalBottomSheet extends StatefulWidget { | @@ -100,7 +97,7 @@ class ModalBottomSheet extends StatefulWidget { | ||
100 | 97 | ||
101 | /// A builder for the contents of the sheet. | 98 | /// A builder for the contents of the sheet. |
102 | /// | 99 | /// |
103 | - final ScrollWidgetBuilder builder; | 100 | + final Widget child; |
104 | 101 | ||
105 | /// If true, the bottom sheet can be dragged up and down and dismissed by | 102 | /// If true, the bottom sheet can be dragged up and down and dismissed by |
106 | /// swiping downwards. | 103 | /// swiping downwards. |
@@ -135,7 +132,7 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> | @@ -135,7 +132,7 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> | ||
135 | with TickerProviderStateMixin { | 132 | with TickerProviderStateMixin { |
136 | final GlobalKey _childKey = GlobalKey(debugLabel: 'BottomSheet child'); | 133 | final GlobalKey _childKey = GlobalKey(debugLabel: 'BottomSheet child'); |
137 | 134 | ||
138 | - ScrollController _scrollController; | 135 | + ScrollController get _scrollController => widget.scrollController; |
139 | 136 | ||
140 | AnimationController _bounceDragController; | 137 | AnimationController _bounceDragController; |
141 | 138 | ||
@@ -267,6 +264,9 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> | @@ -267,6 +264,9 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> | ||
267 | //Check if there is more than 1 attached ScrollController e.g. swiping page in PageView | 264 | //Check if there is more than 1 attached ScrollController e.g. swiping page in PageView |
268 | if (_scrollController.positions.length > 1) return; | 265 | if (_scrollController.positions.length > 1) return; |
269 | 266 | ||
267 | + if (_scrollController != | ||
268 | + Scrollable.of(notification.context).widget.controller) return; | ||
269 | + | ||
270 | final scrollPosition = _scrollController.position; | 270 | final scrollPosition = _scrollController.position; |
271 | 271 | ||
272 | if (scrollPosition.axis == Axis.horizontal) return; | 272 | if (scrollPosition.axis == Axis.horizontal) return; |
@@ -277,14 +277,6 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> | @@ -277,14 +277,6 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> | ||
277 | : scrollPosition.maxScrollExtent - scrollPosition.pixels; | 277 | : scrollPosition.maxScrollExtent - scrollPosition.pixels; |
278 | 278 | ||
279 | if (offset <= 0) { | 279 | if (offset <= 0) { |
280 | - // Check if listener is same from scrollController. | ||
281 | - // TODO: Improve the way it checks if it the same view controller | ||
282 | - // Use PrimaryScrollController | ||
283 | - if (_scrollController.position.pixels != notification.metrics.pixels && | ||
284 | - !(_scrollController.position.pixels == 0 && | ||
285 | - notification.metrics.pixels >= 0)) { | ||
286 | - return; | ||
287 | - } | ||
288 | // Clamping Scroll Physics end with a ScrollEndNotification with a DragEndDetail class | 280 | // Clamping Scroll Physics end with a ScrollEndNotification with a DragEndDetail class |
289 | // while Bouncing Scroll Physics or other physics that Overflow don't return a drag end info | 281 | // while Bouncing Scroll Physics or other physics that Overflow don't return a drag end info |
290 | 282 | ||
@@ -297,7 +289,7 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> | @@ -297,7 +289,7 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> | ||
297 | return; | 289 | return; |
298 | } | 290 | } |
299 | 291 | ||
300 | -// Otherwise the calculate the velocity with a VelocityTracker | 292 | + // Otherwise the calculate the velocity with a VelocityTracker |
301 | if (_velocityTracker == null) { | 293 | if (_velocityTracker == null) { |
302 | final pointerKind = defaultPointerDeviceKind(context); | 294 | final pointerKind = defaultPointerDeviceKind(context); |
303 | _velocityTracker = VelocityTracker(); | 295 | _velocityTracker = VelocityTracker(); |
@@ -331,7 +323,7 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> | @@ -331,7 +323,7 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> | ||
331 | animationCurve = _defaultCurve; | 323 | animationCurve = _defaultCurve; |
332 | _bounceDragController = | 324 | _bounceDragController = |
333 | AnimationController(vsync: this, duration: Duration(milliseconds: 300)); | 325 | AnimationController(vsync: this, duration: Duration(milliseconds: 300)); |
334 | - _scrollController = widget.scrollController ?? ScrollController(); | 326 | + |
335 | // Todo: Check if we can remove scroll Controller | 327 | // Todo: Check if we can remove scroll Controller |
336 | super.initState(); | 328 | super.initState(); |
337 | } | 329 | } |
@@ -343,8 +335,7 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> | @@ -343,8 +335,7 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> | ||
343 | curve: Curves.easeOutSine, | 335 | curve: Curves.easeOutSine, |
344 | ); | 336 | ); |
345 | 337 | ||
346 | - var child = widget.builder(context, _scrollController); | ||
347 | - | 338 | + var child = widget.child; |
348 | if (widget.containerBuilder != null) { | 339 | if (widget.containerBuilder != null) { |
349 | child = widget.containerBuilder( | 340 | child = widget.containerBuilder( |
350 | context, | 341 | context, |
@@ -402,8 +393,10 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> | @@ -402,8 +393,10 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> | ||
402 | child: RepaintBoundary(child: child), | 393 | child: RepaintBoundary(child: child), |
403 | ); | 394 | ); |
404 | 395 | ||
405 | - return PrimaryScrollStatusBarHandler( | ||
406 | - scrollController: _scrollController, child: child); | 396 | + return ScrollToTopStatusBarHandler( |
397 | + child: child, | ||
398 | + scrollController: _scrollController, | ||
399 | + ); | ||
407 | } | 400 | } |
408 | } | 401 | } |
409 | 402 |
@@ -3,6 +3,7 @@ import 'dart:async'; | @@ -3,6 +3,7 @@ import 'dart:async'; | ||
3 | import 'package:flutter/cupertino.dart'; | 3 | import 'package:flutter/cupertino.dart'; |
4 | import 'package:flutter/foundation.dart'; | 4 | import 'package:flutter/foundation.dart'; |
5 | import 'package:flutter/material.dart'; | 5 | import 'package:flutter/material.dart'; |
6 | +import 'package:modal_bottom_sheet/src/utils/modal_scroll_controller.dart'; | ||
6 | 7 | ||
7 | import '../modal_bottom_sheet.dart'; | 8 | import '../modal_bottom_sheet.dart'; |
8 | 9 | ||
@@ -15,7 +16,6 @@ class _ModalBottomSheet<T> extends StatefulWidget { | @@ -15,7 +16,6 @@ class _ModalBottomSheet<T> extends StatefulWidget { | ||
15 | this.route, | 16 | this.route, |
16 | this.secondAnimationController, | 17 | this.secondAnimationController, |
17 | this.bounce = false, | 18 | this.bounce = false, |
18 | - this.scrollController, | ||
19 | this.expanded = false, | 19 | this.expanded = false, |
20 | this.enableDrag = true, | 20 | this.enableDrag = true, |
21 | this.animationCurve, | 21 | this.animationCurve, |
@@ -30,7 +30,6 @@ class _ModalBottomSheet<T> extends StatefulWidget { | @@ -30,7 +30,6 @@ class _ModalBottomSheet<T> extends StatefulWidget { | ||
30 | final bool enableDrag; | 30 | final bool enableDrag; |
31 | final AnimationController secondAnimationController; | 31 | final AnimationController secondAnimationController; |
32 | final Curve animationCurve; | 32 | final Curve animationCurve; |
33 | - final ScrollController scrollController; | ||
34 | 33 | ||
35 | @override | 34 | @override |
36 | _ModalBottomSheetState<T> createState() => _ModalBottomSheetState<T>(); | 35 | _ModalBottomSheetState<T> createState() => _ModalBottomSheetState<T>(); |
@@ -56,6 +55,8 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> { | @@ -56,6 +55,8 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> { | ||
56 | return null; | 55 | return null; |
57 | } | 56 | } |
58 | 57 | ||
58 | + ScrollController _scrollController; | ||
59 | + | ||
59 | @override | 60 | @override |
60 | void initState() { | 61 | void initState() { |
61 | widget.route.animation.addListener(updateController); | 62 | widget.route.animation.addListener(updateController); |
@@ -65,6 +66,7 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> { | @@ -65,6 +66,7 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> { | ||
65 | @override | 66 | @override |
66 | void dispose() { | 67 | void dispose() { |
67 | widget.route.animation.removeListener(updateController); | 68 | widget.route.animation.removeListener(updateController); |
69 | + _scrollController?.dispose(); | ||
68 | super.dispose(); | 70 | super.dispose(); |
69 | } | 71 | } |
70 | 72 | ||
@@ -75,41 +77,47 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> { | @@ -75,41 +77,47 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> { | ||
75 | @override | 77 | @override |
76 | Widget build(BuildContext context) { | 78 | Widget build(BuildContext context) { |
77 | assert(debugCheckHasMediaQuery(context)); | 79 | assert(debugCheckHasMediaQuery(context)); |
78 | - | ||
79 | - return AnimatedBuilder( | ||
80 | - animation: widget.route._animationController, | ||
81 | - builder: (BuildContext context, Widget child) { | ||
82 | - // Disable the initial animation when accessible navigation is on so | ||
83 | - // that the semantics are added to the tree at the correct time. | ||
84 | - return Semantics( | ||
85 | - scopesRoute: true, | ||
86 | - namesRoute: true, | ||
87 | - label: _getRouteLabel(), | ||
88 | - explicitChildNodes: true, | ||
89 | - child: ModalBottomSheet( | ||
90 | - closeProgressThreshold: widget.closeProgressThreshold, | ||
91 | - expanded: widget.route.expanded, | ||
92 | - containerBuilder: widget.route.containerBuilder, | ||
93 | - animationController: widget.route._animationController, | ||
94 | - shouldClose: widget.route._hasScopedWillPopCallback | ||
95 | - ? () async { | ||
96 | - final willPop = await widget.route.willPop(); | ||
97 | - return willPop != RoutePopDisposition.doNotPop; | 80 | + final scrollController = PrimaryScrollController.of(context) ?? |
81 | + (_scrollController ??= ScrollController()); | ||
82 | + return ModalScrollController( | ||
83 | + controller: scrollController, | ||
84 | + child: Builder( | ||
85 | + builder: (context) => AnimatedBuilder( | ||
86 | + animation: widget.route._animationController, | ||
87 | + builder: (BuildContext context, Widget child) { | ||
88 | + // Disable the initial animation when accessible navigation is on so | ||
89 | + // that the semantics are added to the tree at the correct time. | ||
90 | + return Semantics( | ||
91 | + scopesRoute: true, | ||
92 | + namesRoute: true, | ||
93 | + label: _getRouteLabel(), | ||
94 | + explicitChildNodes: true, | ||
95 | + child: ModalBottomSheet( | ||
96 | + expanded: widget.route.expanded, | ||
97 | + containerBuilder: widget.route.containerBuilder, | ||
98 | + animationController: widget.route._animationController, | ||
99 | + shouldClose: widget.route._hasScopedWillPopCallback | ||
100 | + ? () async { | ||
101 | + final willPop = await widget.route.willPop(); | ||
102 | + return willPop != RoutePopDisposition.doNotPop; | ||
103 | + } | ||
104 | + : null, | ||
105 | + onClosing: () { | ||
106 | + if (widget.route.isCurrent) { | ||
107 | + Navigator.of(context).pop(); | ||
98 | } | 108 | } |
99 | - : null, | ||
100 | - onClosing: () { | ||
101 | - if (widget.route.isCurrent) { | ||
102 | - Navigator.of(context).pop(); | ||
103 | - } | ||
104 | - }, | ||
105 | - builder: widget.route.builder, | ||
106 | - enableDrag: widget.enableDrag, | ||
107 | - bounce: widget.bounce, | ||
108 | - scrollController: widget.scrollController, | ||
109 | - animationCurve: widget.animationCurve, | ||
110 | - ), | ||
111 | - ); | ||
112 | - }, | 109 | + }, |
110 | + child: child, | ||
111 | + enableDrag: widget.enableDrag, | ||
112 | + bounce: widget.bounce, | ||
113 | + scrollController: scrollController, | ||
114 | + animationCurve: widget.animationCurve, | ||
115 | + ), | ||
116 | + ); | ||
117 | + }, | ||
118 | + child: widget.route.builder(context), | ||
119 | + ), | ||
120 | + ), | ||
113 | ); | 121 | ); |
114 | } | 122 | } |
115 | } | 123 | } |
@@ -137,7 +145,7 @@ class ModalBottomSheetRoute<T> extends PopupRoute<T> { | @@ -137,7 +145,7 @@ class ModalBottomSheetRoute<T> extends PopupRoute<T> { | ||
137 | 145 | ||
138 | final double closeProgressThreshold; | 146 | final double closeProgressThreshold; |
139 | final WidgetWithChildBuilder containerBuilder; | 147 | final WidgetWithChildBuilder containerBuilder; |
140 | - final ScrollWidgetBuilder builder; | 148 | + final WidgetBuilder builder; |
141 | final bool expanded; | 149 | final bool expanded; |
142 | final bool bounce; | 150 | final bool bounce; |
143 | final Color modalBarrierColor; | 151 | final Color modalBarrierColor; |
@@ -189,7 +197,6 @@ class ModalBottomSheetRoute<T> extends PopupRoute<T> { | @@ -189,7 +197,6 @@ class ModalBottomSheetRoute<T> extends PopupRoute<T> { | ||
189 | route: this, | 197 | route: this, |
190 | secondAnimationController: secondAnimationController, | 198 | secondAnimationController: secondAnimationController, |
191 | expanded: expanded, | 199 | expanded: expanded, |
192 | - scrollController: scrollController, | ||
193 | bounce: bounce, | 200 | bounce: bounce, |
194 | enableDrag: enableDrag, | 201 | enableDrag: enableDrag, |
195 | animationCurve: animationCurve, | 202 | animationCurve: animationCurve, |
@@ -218,7 +225,7 @@ class ModalBottomSheetRoute<T> extends PopupRoute<T> { | @@ -218,7 +225,7 @@ class ModalBottomSheetRoute<T> extends PopupRoute<T> { | ||
218 | /// Shows a modal material design bottom sheet. | 225 | /// Shows a modal material design bottom sheet. |
219 | Future<T> showCustomModalBottomSheet<T>({ | 226 | Future<T> showCustomModalBottomSheet<T>({ |
220 | @required BuildContext context, | 227 | @required BuildContext context, |
221 | - @required ScrollWidgetBuilder builder, | 228 | + @required WidgetBuilder builder, |
222 | @required WidgetWithChildBuilder containerWidget, | 229 | @required WidgetWithChildBuilder containerWidget, |
223 | Color backgroundColor, | 230 | Color backgroundColor, |
224 | double elevation, | 231 | double elevation, |
@@ -232,7 +239,6 @@ Future<T> showCustomModalBottomSheet<T>({ | @@ -232,7 +239,6 @@ Future<T> showCustomModalBottomSheet<T>({ | ||
232 | bool useRootNavigator = false, | 239 | bool useRootNavigator = false, |
233 | bool isDismissible = true, | 240 | bool isDismissible = true, |
234 | bool enableDrag = true, | 241 | bool enableDrag = true, |
235 | - ScrollController scrollController, | ||
236 | Duration duration, | 242 | Duration duration, |
237 | }) async { | 243 | }) async { |
238 | assert(context != null); | 244 | assert(context != null); |
@@ -71,7 +71,7 @@ class BarBottomSheet extends StatelessWidget { | @@ -71,7 +71,7 @@ class BarBottomSheet extends StatelessWidget { | ||
71 | 71 | ||
72 | Future<T> showBarModalBottomSheet<T>({ | 72 | Future<T> showBarModalBottomSheet<T>({ |
73 | @required BuildContext context, | 73 | @required BuildContext context, |
74 | - @required ScrollWidgetBuilder builder, | 74 | + @required WidgetBuilder builder, |
75 | Color backgroundColor, | 75 | Color backgroundColor, |
76 | double elevation, | 76 | double elevation, |
77 | ShapeBorder shape, | 77 | ShapeBorder shape, |
@@ -67,7 +67,7 @@ class _CupertinoBottomSheetContainer extends StatelessWidget { | @@ -67,7 +67,7 @@ class _CupertinoBottomSheetContainer extends StatelessWidget { | ||
67 | 67 | ||
68 | Future<T> showCupertinoModalBottomSheet<T>({ | 68 | Future<T> showCupertinoModalBottomSheet<T>({ |
69 | @required BuildContext context, | 69 | @required BuildContext context, |
70 | - @required ScrollWidgetBuilder builder, | 70 | + @required WidgetBuilder builder, |
71 | Color backgroundColor, | 71 | Color backgroundColor, |
72 | double elevation, | 72 | double elevation, |
73 | double closeProgressThreshold, | 73 | double closeProgressThreshold, |
@@ -139,7 +139,7 @@ class CupertinoModalBottomSheetRoute<T> extends ModalBottomSheetRoute<T> { | @@ -139,7 +139,7 @@ class CupertinoModalBottomSheetRoute<T> extends ModalBottomSheetRoute<T> { | ||
139 | final Color transitionBackgroundColor; | 139 | final Color transitionBackgroundColor; |
140 | 140 | ||
141 | CupertinoModalBottomSheetRoute({ | 141 | CupertinoModalBottomSheetRoute({ |
142 | - ScrollWidgetBuilder builder, | 142 | + WidgetBuilder builder, |
143 | WidgetWithChildBuilder containerBuilder, | 143 | WidgetWithChildBuilder containerBuilder, |
144 | double closeProgressThreshold, | 144 | double closeProgressThreshold, |
145 | String barrierLabel, | 145 | String barrierLabel, |
@@ -321,8 +321,8 @@ class CupertinoScaffold extends StatefulWidget { | @@ -321,8 +321,8 @@ class CupertinoScaffold extends StatefulWidget { | ||
321 | 321 | ||
322 | static Future<T> showCupertinoModalBottomSheet<T>({ | 322 | static Future<T> showCupertinoModalBottomSheet<T>({ |
323 | @required BuildContext context, | 323 | @required BuildContext context, |
324 | - @required ScrollWidgetBuilder builder, | ||
325 | double closeProgressThreshold, | 324 | double closeProgressThreshold, |
325 | + @required WidgetBuilder builder, | ||
326 | Curve animationCurve, | 326 | Curve animationCurve, |
327 | Curve previousRouteAnimationCurve, | 327 | Curve previousRouteAnimationCurve, |
328 | Color backgroundColor, | 328 | Color backgroundColor, |
@@ -5,8 +5,8 @@ import 'dart:async'; | @@ -5,8 +5,8 @@ import 'dart:async'; | ||
5 | /// Shows a modal material design bottom sheet. | 5 | /// Shows a modal material design bottom sheet. |
6 | Future<T> showMaterialModalBottomSheet<T>({ | 6 | Future<T> showMaterialModalBottomSheet<T>({ |
7 | @required BuildContext context, | 7 | @required BuildContext context, |
8 | - @required ScrollWidgetBuilder builder, | ||
9 | double closeProgressThreshold, | 8 | double closeProgressThreshold, |
9 | + @required WidgetBuilder builder, | ||
10 | Color backgroundColor, | 10 | Color backgroundColor, |
11 | double elevation, | 11 | double elevation, |
12 | ShapeBorder shape, | 12 | ShapeBorder shape, |
lib/src/utils/modal_scroll_controller.dart
0 → 100644
1 | +import 'package:flutter/rendering.dart'; | ||
2 | +import 'package:flutter/widgets.dart'; | ||
3 | + | ||
4 | +/// Associates a [ScrollController] with a subtree. | ||
5 | +/// | ||
6 | +/// This mechanism can be used to provide default behavior for scroll views in a | ||
7 | +/// subtree inside a modal bottom sheet. | ||
8 | +/// | ||
9 | +/// We want to remove this and use [PrimaryScrollController]. | ||
10 | +/// This issue should be solved first https://github.com/flutter/flutter/issues/64236 | ||
11 | +/// | ||
12 | +/// See [PrimaryScrollController] | ||
13 | +class ModalScrollController extends InheritedWidget { | ||
14 | + /// Creates a widget that associates a [ScrollController] with a subtree. | ||
15 | + ModalScrollController({ | ||
16 | + Key key, | ||
17 | + @required this.controller, | ||
18 | + @required Widget child, | ||
19 | + }) : assert(controller != null), | ||
20 | + super( | ||
21 | + key: key, | ||
22 | + child: PrimaryScrollController( | ||
23 | + controller: controller, | ||
24 | + child: child, | ||
25 | + ), | ||
26 | + ); | ||
27 | + | ||
28 | + /// The [ScrollController] associated with the subtree. | ||
29 | + /// | ||
30 | + /// See also: | ||
31 | + /// | ||
32 | + /// * [ScrollView.controller], which discusses the purpose of specifying a | ||
33 | + /// scroll controller. | ||
34 | + final ScrollController controller; | ||
35 | + | ||
36 | + /// Returns the [ScrollController] most closely associated with the given | ||
37 | + /// context. | ||
38 | + /// | ||
39 | + /// Returns null if there is no [ScrollController] associated with the given | ||
40 | + /// context. | ||
41 | + static ScrollController of(BuildContext context) { | ||
42 | + final ModalScrollController result = | ||
43 | + context.dependOnInheritedWidgetOfExactType<ModalScrollController>(); | ||
44 | + return result?.controller; | ||
45 | + } | ||
46 | + | ||
47 | + @override | ||
48 | + bool updateShouldNotify(ModalScrollController oldWidget) => | ||
49 | + controller != oldWidget.controller; | ||
50 | + | ||
51 | + @override | ||
52 | + void debugFillProperties(DiagnosticPropertiesBuilder properties) { | ||
53 | + super.debugFillProperties(properties); | ||
54 | + properties.add(DiagnosticsProperty<ScrollController>( | ||
55 | + 'controller', controller, | ||
56 | + ifNull: 'no controller', showName: false)); | ||
57 | + } | ||
58 | +} |
1 | import 'package:flutter/widgets.dart'; | 1 | import 'package:flutter/widgets.dart'; |
2 | 2 | ||
3 | -/// Creates a primary scroll controller that will | ||
4 | -/// scroll to the top when tapped on the status bar | 3 | +/// Widget that that will scroll to the top the ScrollController |
4 | +/// when tapped on the status bar | ||
5 | /// | 5 | /// |
6 | -class PrimaryScrollStatusBarHandler extends StatefulWidget { | ||
7 | - final ScrollController scrollController; | 6 | +class ScrollToTopStatusBarHandler extends StatefulWidget { |
8 | final Widget child; | 7 | final Widget child; |
8 | + final ScrollController scrollController; | ||
9 | + | ||
10 | + const ScrollToTopStatusBarHandler({ | ||
11 | + Key key, | ||
12 | + @required this.child, | ||
13 | + @required this.scrollController, | ||
14 | + }) : super(key: key); | ||
9 | 15 | ||
10 | - const PrimaryScrollStatusBarHandler( | ||
11 | - {Key key, this.child, this.scrollController}) | ||
12 | - : super(key: key); | ||
13 | @override | 16 | @override |
14 | - _PrimaryScrollWidgetState createState() => _PrimaryScrollWidgetState(); | 17 | + _ScrollToTopStatusBarState createState() => _ScrollToTopStatusBarState(); |
15 | } | 18 | } |
16 | 19 | ||
17 | -class _PrimaryScrollWidgetState extends State<PrimaryScrollStatusBarHandler> { | ||
18 | - ScrollController controller; | ||
19 | - | 20 | +class _ScrollToTopStatusBarState extends State<ScrollToTopStatusBarHandler> { |
20 | @override | 21 | @override |
21 | void initState() { | 22 | void initState() { |
22 | - controller = widget.scrollController ?? ScrollController(); | ||
23 | super.initState(); | 23 | super.initState(); |
24 | } | 24 | } |
25 | 25 | ||
26 | @override | 26 | @override |
27 | Widget build(BuildContext context) { | 27 | Widget build(BuildContext context) { |
28 | - return PrimaryScrollController( | ||
29 | - controller: controller, | ||
30 | - child: Stack( | ||
31 | - fit: StackFit.expand, | ||
32 | - children: [ | ||
33 | - widget.child, | ||
34 | - Positioned( | ||
35 | - top: 0, | ||
36 | - left: 0, | ||
37 | - right: 0, | ||
38 | - height: MediaQuery.of(context).padding.top, | ||
39 | - child: Builder( | ||
40 | - builder: (context) => GestureDetector( | ||
41 | - behavior: HitTestBehavior.opaque, | ||
42 | - onTap: () => _handleStatusBarTap(context), | ||
43 | - // iOS accessibility automatically adds scroll-to-top to the clock in the status bar | ||
44 | - excludeFromSemantics: true, | ||
45 | - ), | 28 | + return Stack( |
29 | + fit: StackFit.expand, | ||
30 | + children: [ | ||
31 | + widget.child, | ||
32 | + Positioned( | ||
33 | + top: 0, | ||
34 | + left: 0, | ||
35 | + right: 0, | ||
36 | + height: MediaQuery.of(context).padding.top, | ||
37 | + child: Builder( | ||
38 | + builder: (context) => 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, | ||
46 | ), | 43 | ), |
47 | ), | 44 | ), |
48 | - ], | ||
49 | - ), | 45 | + ), |
46 | + ], | ||
50 | ); | 47 | ); |
51 | } | 48 | } |
52 | 49 | ||
53 | void _handleStatusBarTap(BuildContext context) { | 50 | void _handleStatusBarTap(BuildContext context) { |
54 | - final controller = PrimaryScrollController.of(context); | ||
55 | - if (controller.hasClients) { | 51 | + final controller = widget.scrollController; |
52 | + if (controller != null && controller.hasClients) { | ||
56 | controller.animateTo( | 53 | controller.animateTo( |
57 | 0.0, | 54 | 0.0, |
58 | duration: const Duration(milliseconds: 300), | 55 | duration: const Duration(milliseconds: 300), |
-
Please register or login to post a comment