Revert DraggableScrollableSheet controller changes (#112293)

diff --git a/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart b/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart
index b3ff11d..0a6e647 100644
--- a/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart
+++ b/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart
@@ -21,7 +21,6 @@
 import 'scroll_position.dart';
 import 'scroll_position_with_single_context.dart';
 import 'scroll_simulation.dart';
-import 'value_listenable_builder.dart';
 
 /// The signature of a method that provides a [BuildContext] and
 /// [ScrollController] for building a widget that may overflow the draggable
@@ -489,6 +488,7 @@
     required this.snap,
     required this.snapSizes,
     required this.initialSize,
+    required this.onSizeChanged,
     this.snapAnimationDuration,
     ValueNotifier<double>? currentSize,
     bool? hasDragged,
@@ -500,7 +500,8 @@
         assert(maxSize <= 1),
         assert(minSize <= initialSize),
         assert(initialSize <= maxSize),
-        _currentSize = currentSize ?? ValueNotifier<double>(initialSize),
+        _currentSize = (currentSize ?? ValueNotifier<double>(initialSize))
+          ..addListener(onSizeChanged),
         availablePixels = double.infinity,
         hasDragged = hasDragged ?? false,
         hasChanged = hasChanged ?? false;
@@ -514,6 +515,7 @@
   final Duration? snapAnimationDuration;
   final double initialSize;
   final ValueNotifier<double> _currentSize;
+  final VoidCallback onSizeChanged;
   double availablePixels;
 
   // Used to disable snapping until the user has dragged on the sheet.
@@ -593,12 +595,17 @@
     return size / maxSize * availablePixels;
   }
 
+  void dispose() {
+    _currentSize.removeListener(onSizeChanged);
+  }
+
   _DraggableSheetExtent copyWith({
     required double minSize,
     required double maxSize,
     required bool snap,
     required List<double> snapSizes,
     required double initialSize,
+    required VoidCallback onSizeChanged,
     Duration? snapAnimationDuration,
   }) {
     return _DraggableSheetExtent(
@@ -608,6 +615,7 @@
       snapSizes: snapSizes,
       snapAnimationDuration: snapAnimationDuration,
       initialSize: initialSize,
+      onSizeChanged: onSizeChanged,
       // Set the current size to the possibly updated initial size if the sheet
       // hasn't changed yet.
       currentSize: ValueNotifier<double>(hasChanged
@@ -633,6 +641,7 @@
       snapSizes: _impliedSnapSizes(),
       snapAnimationDuration: widget.snapAnimationDuration,
       initialSize: widget.initialChildSize,
+      onSizeChanged: _setExtent,
     );
     _scrollController = _DraggableScrollableSheetScrollController(extent: _extent);
     widget.controller?._attach(_scrollController);
@@ -663,10 +672,6 @@
   @override
   void didUpdateWidget(covariant DraggableScrollableSheet oldWidget) {
     super.didUpdateWidget(oldWidget);
-    if (widget.controller != oldWidget.controller) {
-      oldWidget.controller?._detach();
-      widget.controller?._attach(_scrollController);
-    }
     _replaceExtent(oldWidget);
   }
 
@@ -678,22 +683,24 @@
     }
   }
 
+  void _setExtent() {
+    setState(() {
+      // _extent has been updated when this is called.
+    });
+  }
+
   @override
   Widget build(BuildContext context) {
-    return ValueListenableBuilder<double>(
-      valueListenable: _extent._currentSize,
-      builder: (BuildContext context, double currentSize, Widget? child) => LayoutBuilder(
-        builder: (BuildContext context, BoxConstraints constraints) {
-          _extent.availablePixels = widget.maxChildSize * constraints.biggest.height;
-          final Widget sheet = FractionallySizedBox(
-            heightFactor: currentSize,
-            alignment: Alignment.bottomCenter,
-            child: child,
-          );
-          return widget.expand ? SizedBox.expand(child: sheet) : sheet;
-        },
-      ),
-      child: widget.builder(context, _scrollController),
+    return LayoutBuilder(
+      builder: (BuildContext context, BoxConstraints constraints) {
+        _extent.availablePixels = widget.maxChildSize * constraints.biggest.height;
+        final Widget sheet = FractionallySizedBox(
+          heightFactor: _extent.currentSize,
+          alignment: Alignment.bottomCenter,
+          child: widget.builder(context, _scrollController),
+        );
+        return widget.expand ? SizedBox.expand(child: sheet) : sheet;
+      },
     );
   }
 
@@ -701,11 +708,13 @@
   void dispose() {
     widget.controller?._detach();
     _scrollController.dispose();
+    _extent.dispose();
     super.dispose();
   }
 
   void _replaceExtent(covariant DraggableScrollableSheet oldWidget) {
     final _DraggableSheetExtent previousExtent = _extent;
+    _extent.dispose();
     _extent = _extent.copyWith(
       minSize: widget.minChildSize,
       maxSize: widget.maxChildSize,
@@ -713,15 +722,14 @@
       snapSizes: _impliedSnapSizes(),
       snapAnimationDuration: widget.snapAnimationDuration,
       initialSize: widget.initialChildSize,
+      onSizeChanged: _setExtent,
     );
     // Modify the existing scroll controller instead of replacing it so that
     // developers listening to the controller do not have to rebuild their listeners.
     _scrollController.extent = _extent;
     // If an external facing controller was provided, let it know that the
     // extent has been replaced.
-    if (widget.controller == oldWidget.controller) {
-      widget.controller?._onExtentReplaced(previousExtent);
-    }
+    widget.controller?._onExtentReplaced(previousExtent);
     if (widget.snap
         && (widget.snap != oldWidget.snap || widget.snapSizes != oldWidget.snapSizes)
         && _scrollController.hasClients
diff --git a/packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart b/packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart
index 8043325..6ae2fc6 100644
--- a/packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart
+++ b/packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart
@@ -1465,95 +1465,4 @@
       closeTo(.6, precisionErrorTolerance),
     );
   });
-
-  testWidgets('DraggableScrollableSheet should not rebuild every frame while dragging', (WidgetTester tester) async {
-    // Regression test for https://github.com/flutter/flutter/issues/67219
-    int buildCount = 0;
-    await tester.pumpWidget(MaterialApp(
-      home: StatefulBuilder(
-        builder: (BuildContext context, StateSetter setState) => Scaffold(
-          body: DraggableScrollableSheet(
-            initialChildSize: 0.25,
-            snap: true,
-            snapSizes: const <double>[0.25, 0.5, 1.0],
-            builder: (BuildContext context, ScrollController scrollController) {
-              buildCount++;
-              return ListView(
-                controller: scrollController,
-                children: <Widget>[
-                  const Text('Drag me!'),
-                  ElevatedButton(
-                    onPressed: () => setState(() {}),
-                    child: const Text('Rebuild'),
-                  ),
-                  Container(
-                    height: 10000,
-                    color: Colors.blue,
-                  ),
-                ],
-              );
-            },
-          ),
-        ),
-      ),
-    ));
-
-    expect(buildCount, 1);
-
-    await tester.fling(find.text('Drag me!'), const Offset(0, -300), 300);
-    await tester.pumpAndSettle();
-
-    // No need to rebuild the scrollable sheet, as only position has changed.
-    expect(buildCount, 1);
-
-    await tester.tap(find.text('Rebuild'));
-    await tester.pump();
-
-    // DraggableScrollableSheet has rebuilt, so expect the builder to be called.
-    expect(buildCount, 2);
-  });
-
-  testWidgets('DraggableScrollableSheet controller can be changed', (WidgetTester tester) async {
-    final DraggableScrollableController controller1 = DraggableScrollableController();
-    final DraggableScrollableController controller2 = DraggableScrollableController();
-    DraggableScrollableController controller = controller1;
-    await tester.pumpWidget(MaterialApp(
-      home: StatefulBuilder(
-        builder: (BuildContext context, StateSetter setState) => Scaffold(
-          body: DraggableScrollableSheet(
-            initialChildSize: 0.25,
-            snap: true,
-            snapSizes: const <double>[0.25, 0.5, 1.0],
-            controller: controller,
-            builder: (BuildContext context, ScrollController scrollController) {
-              return ListView(
-                controller: scrollController,
-                children: <Widget>[
-                  ElevatedButton(
-                    onPressed: () => setState(() {
-                      controller = controller2;
-                    }),
-                    child: const Text('Switch controller'),
-                  ),
-                  Container(
-                    height: 10000,
-                    color: Colors.blue,
-                  ),
-                ],
-              );
-            },
-          ),
-        ),
-      ),
-    ));
-
-    expect(controller1.isAttached, true);
-    expect(controller2.isAttached, false);
-
-    await tester.tap(find.text('Switch controller'));
-    await tester.pump();
-
-    expect(controller1.isAttached, false);
-    expect(controller2.isAttached, true);
-  });
 }