Jaime Blasco

Temporary replace of PrimaryScrollController

 This issue would be solved first https://github.com/flutter/flutter/issues/64236
@@ -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 - primary: true, 95 + controller: ModalScrollController.of(context),
96 slivers: <Widget>[ 96 slivers: <Widget>[
97 SliverSafeArea( 97 SliverSafeArea(
98 bottom: false, 98 bottom: false,
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 -  
6 -  
7 const ComplexModal({Key key}) : 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) {
11 - final scrollController = PrimaryScrollController.of(context);  
12 return Material( 10 return Material(
13 child: WillPopScope( 11 child: WillPopScope(
14 onWillPop: () async { 12 onWillPop: () async {
@@ -47,8 +45,7 @@ class ComplexModal extends StatelessWidget { @@ -47,8 +45,7 @@ class ComplexModal extends StatelessWidget {
47 bottom: false, 45 bottom: false,
48 child: ListView( 46 child: ListView(
49 shrinkWrap: true, 47 shrinkWrap: true,
50 -  
51 - controller: scrollController, 48 + controller: ModalScrollController.of(context),
52 children: ListTile.divideTiles( 49 children: ListTile.divideTiles(
53 context: context, 50 context: context,
54 tiles: List.generate( 51 tiles: List.generate(
@@ -9,7 +9,6 @@ class ModalInsideModal extends StatelessWidget { @@ -9,7 +9,6 @@ class ModalInsideModal extends StatelessWidget {
9 9
10 @override 10 @override
11 Widget build(BuildContext context) { 11 Widget build(BuildContext context) {
12 - final scrollController = PrimaryScrollController.of(context);  
13 return Material( 12 return Material(
14 child: CupertinoPageScaffold( 13 child: CupertinoPageScaffold(
15 navigationBar: CupertinoNavigationBar( 14 navigationBar: CupertinoNavigationBar(
@@ -19,7 +18,7 @@ class ModalInsideModal extends StatelessWidget { @@ -19,7 +18,7 @@ class ModalInsideModal extends StatelessWidget {
19 child: ListView( 18 child: ListView(
20 reverse: reverse, 19 reverse: reverse,
21 shrinkWrap: true, 20 shrinkWrap: true,
22 - controller: scrollController, 21 + controller: ModalScrollController.of(context),
23 physics: ClampingScrollPhysics(), 22 physics: ClampingScrollPhysics(),
24 children: ListTile.divideTiles( 23 children: ListTile.divideTiles(
25 context: context, 24 context: 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 6
@@ -8,7 +9,6 @@ class ModalWithNavigator extends StatelessWidget { @@ -8,7 +9,6 @@ class ModalWithNavigator extends StatelessWidget {
8 9
9 @override 10 @override
10 Widget build(BuildContext context) { 11 Widget build(BuildContext context) {
11 - final scrollController = PrimaryScrollController.of(context);  
12 return Material( 12 return Material(
13 child: Navigator( 13 child: Navigator(
14 onGenerateRoute: (_) => MaterialPageRoute( 14 onGenerateRoute: (_) => MaterialPageRoute(
@@ -20,7 +20,7 @@ class ModalWithNavigator extends StatelessWidget { @@ -20,7 +20,7 @@ class ModalWithNavigator extends StatelessWidget {
20 bottom: false, 20 bottom: false,
21 child: ListView( 21 child: ListView(
22 shrinkWrap: true, 22 shrinkWrap: true,
23 - controller: scrollController, 23 + controller: ModalScrollController.of(context),
24 children: ListTile.divideTiles( 24 children: ListTile.divideTiles(
25 context: context, 25 context: context,
26 tiles: List.generate( 26 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 const NestedScrollModal({Key key}) : super(key: key); 6 const NestedScrollModal({Key key}) : super(key: key);
@@ -7,7 +8,6 @@ class NestedScrollModal extends StatelessWidget { @@ -7,7 +8,6 @@ class NestedScrollModal extends StatelessWidget {
7 8
8 @override 9 @override
9 Widget build(BuildContext context) { 10 Widget build(BuildContext context) {
10 - final scrollController = PrimaryScrollController.of(context);  
11 return NestedScrollView( 11 return NestedScrollView(
12 controller: ScrollController(), 12 controller: ScrollController(),
13 physics: ScrollPhysics(parent: PageScrollPhysics()), 13 physics: ScrollPhysics(parent: PageScrollPhysics()),
@@ -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 const ModalWithScroll({Key key}) : super(key: key); 6 const ModalWithScroll({Key key}) : super(key: key);
6 7
7 @override 8 @override
8 Widget build(BuildContext context) { 9 Widget build(BuildContext context) {
9 - final scrollController = PrimaryScrollController.of(context); 10 +
10 return Material( 11 return Material(
11 child: CupertinoPageScaffold( 12 child: CupertinoPageScaffold(
12 navigationBar: CupertinoNavigationBar( 13 navigationBar: CupertinoNavigationBar(
@@ -15,7 +16,7 @@ class ModalWithScroll extends StatelessWidget { @@ -15,7 +16,7 @@ class ModalWithScroll extends StatelessWidget {
15 bottom: false, 16 bottom: false,
16 child: ListView( 17 child: ListView(
17 shrinkWrap: true, 18 shrinkWrap: true,
18 - controller: scrollController, 19 + controller: ModalScrollController.of(context),
19 children: ListTile.divideTiles( 20 children: ListTile.divideTiles(
20 context: context, 21 context: context,
21 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';
@@ -10,7 +10,7 @@ import 'package:flutter/gestures.dart'; @@ -10,7 +10,7 @@ import 'package:flutter/gestures.dart';
10 import 'package:flutter/material.dart'; 10 import 'package:flutter/material.dart';
11 import 'package:flutter/scheduler.dart'; 11 import 'package:flutter/scheduler.dart';
12 import 'package:flutter/widgets.dart'; 12 import 'package:flutter/widgets.dart';
13 -import 'package:modal_bottom_sheet/src/utils/primary_scroll_status_bar.dart'; 13 +import 'package:modal_bottom_sheet/src/utils/scroll_to_top_status_bar.dart';
14 14
15 import 'package:modal_bottom_sheet/src/utils/bottom_sheet_suspended_curve.dart'; 15 import 'package:modal_bottom_sheet/src/utils/bottom_sheet_suspended_curve.dart';
16 16
@@ -282,7 +282,7 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> @@ -282,7 +282,7 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
282 return; 282 return;
283 } 283 }
284 284
285 -// Otherwise the calculate the velocity with a VelocityTracker 285 + // Otherwise the calculate the velocity with a VelocityTracker
286 if (_velocityTracker == null) { 286 if (_velocityTracker == null) {
287 _velocityTracker = VelocityTracker(); 287 _velocityTracker = VelocityTracker();
288 _startTime = DateTime.now(); 288 _startTime = DateTime.now();
@@ -385,7 +385,10 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> @@ -385,7 +385,10 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
385 child: RepaintBoundary(child: child), 385 child: RepaintBoundary(child: child),
386 ); 386 );
387 387
388 - return PrimaryScrollStatusBarHandler(child: child); 388 + return ScrollToTopStatusBarHandler(
  389 + child: child,
  390 + scrollController: _scrollController,
  391 + );
389 } 392 }
390 } 393 }
391 394
@@ -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
@@ -74,10 +75,10 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> { @@ -74,10 +75,10 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> {
74 @override 75 @override
75 Widget build(BuildContext context) { 76 Widget build(BuildContext context) {
76 assert(debugCheckHasMediaQuery(context)); 77 assert(debugCheckHasMediaQuery(context));
77 -  
78 - return PrimaryScrollController(  
79 - controller: PrimaryScrollController.of(context) ??  
80 - (_scrollController ??= ScrollController()), 78 + final scrollController = PrimaryScrollController.of(context) ??
  79 + (_scrollController ??= ScrollController());
  80 + return ModalScrollController(
  81 + controller: scrollController,
81 child: Builder( 82 child: Builder(
82 builder: (context) => AnimatedBuilder( 83 builder: (context) => AnimatedBuilder(
83 animation: widget.route._animationController, 84 animation: widget.route._animationController,
@@ -107,7 +108,7 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> { @@ -107,7 +108,7 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> {
107 child: child, 108 child: child,
108 enableDrag: widget.enableDrag, 109 enableDrag: widget.enableDrag,
109 bounce: widget.bounce, 110 bounce: widget.bounce,
110 - scrollController: PrimaryScrollController.of(context), 111 + scrollController: scrollController,
111 animationCurve: widget.animationCurve, 112 animationCurve: widget.animationCurve,
112 ), 113 ),
113 ); 114 );
  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 { 6 +class ScrollToTopStatusBarHandler extends StatefulWidget {
7 final Widget child; 7 final Widget child;
  8 + final ScrollController scrollController;
8 9
9 - const PrimaryScrollStatusBarHandler({Key key, this.child}) : super(key: key); 10 + const ScrollToTopStatusBarHandler({
  11 + Key key,
  12 + @required this.child,
  13 + @required this.scrollController,
  14 + }) : super(key: key);
10 15
11 @override 16 @override
12 - _PrimaryScrollWidgetState createState() => _PrimaryScrollWidgetState(); 17 + _ScrollToTopStatusBarState createState() => _ScrollToTopStatusBarState();
13 } 18 }
14 19
15 -class _PrimaryScrollWidgetState extends State<PrimaryScrollStatusBarHandler> { 20 +class _ScrollToTopStatusBarState extends State<ScrollToTopStatusBarHandler> {
16 @override 21 @override
17 void initState() { 22 void initState() {
18 super.initState(); 23 super.initState();
@@ -43,7 +48,7 @@ class _PrimaryScrollWidgetState extends State<PrimaryScrollStatusBarHandler> { @@ -43,7 +48,7 @@ class _PrimaryScrollWidgetState extends State<PrimaryScrollStatusBarHandler> {
43 } 48 }
44 49
45 void _handleStatusBarTap(BuildContext context) { 50 void _handleStatusBarTap(BuildContext context) {
46 - final controller = PrimaryScrollController.of(context); 51 + final controller = widget.scrollController;
47 if (controller != null && controller.hasClients) { 52 if (controller != null && controller.hasClients) {
48 controller.animateTo( 53 controller.animateTo(
49 0.0, 54 0.0,