@@ -21,7 +21,6 @@ import 'scroll_physics.dart';
2121import 'scroll_position.dart' ;
2222import 'scroll_position_with_single_context.dart' ;
2323import 'scroll_simulation.dart' ;
24- import 'value_listenable_builder.dart' ;
2524
2625/// The signature of a method that provides a [BuildContext] and
2726/// [ScrollController] for building a widget that may overflow the draggable
@@ -489,6 +488,7 @@ class _DraggableSheetExtent {
489488 required this .snap,
490489 required this .snapSizes,
491490 required this .initialSize,
491+ required this .onSizeChanged,
492492 this .snapAnimationDuration,
493493 ValueNotifier <double >? currentSize,
494494 bool ? hasDragged,
@@ -500,7 +500,8 @@ class _DraggableSheetExtent {
500500 assert (maxSize <= 1 ),
501501 assert (minSize <= initialSize),
502502 assert (initialSize <= maxSize),
503- _currentSize = currentSize ?? ValueNotifier <double >(initialSize),
503+ _currentSize = (currentSize ?? ValueNotifier <double >(initialSize))
504+ ..addListener (onSizeChanged),
504505 availablePixels = double .infinity,
505506 hasDragged = hasDragged ?? false ,
506507 hasChanged = hasChanged ?? false ;
@@ -514,6 +515,7 @@ class _DraggableSheetExtent {
514515 final Duration ? snapAnimationDuration;
515516 final double initialSize;
516517 final ValueNotifier <double > _currentSize;
518+ final VoidCallback onSizeChanged;
517519 double availablePixels;
518520
519521 // Used to disable snapping until the user has dragged on the sheet.
@@ -593,12 +595,17 @@ class _DraggableSheetExtent {
593595 return size / maxSize * availablePixels;
594596 }
595597
598+ void dispose () {
599+ _currentSize.removeListener (onSizeChanged);
600+ }
601+
596602 _DraggableSheetExtent copyWith ({
597603 required double minSize,
598604 required double maxSize,
599605 required bool snap,
600606 required List <double > snapSizes,
601607 required double initialSize,
608+ required VoidCallback onSizeChanged,
602609 Duration ? snapAnimationDuration,
603610 }) {
604611 return _DraggableSheetExtent (
@@ -608,6 +615,7 @@ class _DraggableSheetExtent {
608615 snapSizes: snapSizes,
609616 snapAnimationDuration: snapAnimationDuration,
610617 initialSize: initialSize,
618+ onSizeChanged: onSizeChanged,
611619 // Set the current size to the possibly updated initial size if the sheet
612620 // hasn't changed yet.
613621 currentSize: ValueNotifier <double >(hasChanged
@@ -633,6 +641,7 @@ class _DraggableScrollableSheetState extends State<DraggableScrollableSheet> {
633641 snapSizes: _impliedSnapSizes (),
634642 snapAnimationDuration: widget.snapAnimationDuration,
635643 initialSize: widget.initialChildSize,
644+ onSizeChanged: _setExtent,
636645 );
637646 _scrollController = _DraggableScrollableSheetScrollController (extent: _extent);
638647 widget.controller? ._attach (_scrollController);
@@ -663,10 +672,6 @@ class _DraggableScrollableSheetState extends State<DraggableScrollableSheet> {
663672 @override
664673 void didUpdateWidget (covariant DraggableScrollableSheet oldWidget) {
665674 super .didUpdateWidget (oldWidget);
666- if (widget.controller != oldWidget.controller) {
667- oldWidget.controller? ._detach ();
668- widget.controller? ._attach (_scrollController);
669- }
670675 _replaceExtent (oldWidget);
671676 }
672677
@@ -678,50 +683,53 @@ class _DraggableScrollableSheetState extends State<DraggableScrollableSheet> {
678683 }
679684 }
680685
686+ void _setExtent () {
687+ setState (() {
688+ // _extent has been updated when this is called.
689+ });
690+ }
691+
681692 @override
682693 Widget build (BuildContext context) {
683- return ValueListenableBuilder <double >(
684- valueListenable: _extent._currentSize,
685- builder: (BuildContext context, double currentSize, Widget ? child) => LayoutBuilder (
686- builder: (BuildContext context, BoxConstraints constraints) {
687- _extent.availablePixels = widget.maxChildSize * constraints.biggest.height;
688- final Widget sheet = FractionallySizedBox (
689- heightFactor: currentSize,
690- alignment: Alignment .bottomCenter,
691- child: child,
692- );
693- return widget.expand ? SizedBox .expand (child: sheet) : sheet;
694- },
695- ),
696- child: widget.builder (context, _scrollController),
694+ return LayoutBuilder (
695+ builder: (BuildContext context, BoxConstraints constraints) {
696+ _extent.availablePixels = widget.maxChildSize * constraints.biggest.height;
697+ final Widget sheet = FractionallySizedBox (
698+ heightFactor: _extent.currentSize,
699+ alignment: Alignment .bottomCenter,
700+ child: widget.builder (context, _scrollController),
701+ );
702+ return widget.expand ? SizedBox .expand (child: sheet) : sheet;
703+ },
697704 );
698705 }
699706
700707 @override
701708 void dispose () {
702709 widget.controller? ._detach ();
703710 _scrollController.dispose ();
711+ _extent.dispose ();
704712 super .dispose ();
705713 }
706714
707715 void _replaceExtent (covariant DraggableScrollableSheet oldWidget) {
708716 final _DraggableSheetExtent previousExtent = _extent;
717+ _extent.dispose ();
709718 _extent = _extent.copyWith (
710719 minSize: widget.minChildSize,
711720 maxSize: widget.maxChildSize,
712721 snap: widget.snap,
713722 snapSizes: _impliedSnapSizes (),
714723 snapAnimationDuration: widget.snapAnimationDuration,
715724 initialSize: widget.initialChildSize,
725+ onSizeChanged: _setExtent,
716726 );
717727 // Modify the existing scroll controller instead of replacing it so that
718728 // developers listening to the controller do not have to rebuild their listeners.
719729 _scrollController.extent = _extent;
720730 // If an external facing controller was provided, let it know that the
721731 // extent has been replaced.
722- if (widget.controller == oldWidget.controller) {
723- widget.controller? ._onExtentReplaced (previousExtent);
724- }
732+ widget.controller? ._onExtentReplaced (previousExtent);
725733 if (widget.snap
726734 && (widget.snap != oldWidget.snap || widget.snapSizes != oldWidget.snapSizes)
727735 && _scrollController.hasClients
0 commit comments