Unverified Commit 5c522996 authored by xubaolin's avatar xubaolin Committed by GitHub

fix some DSS bugs (#112142)

parent f22f1344
...@@ -201,8 +201,12 @@ class DraggableScrollableController extends ChangeNotifier { ...@@ -201,8 +201,12 @@ class DraggableScrollableController extends ChangeNotifier {
} }
} }
void _detach() { void _detach({bool disposeExtent = false}) {
_attachedController?.extent._currentSize.removeListener(notifyListeners); if (disposeExtent) {
_attachedController?.extent.dispose();
} else {
_attachedController?.extent._currentSize.removeListener(notifyListeners);
}
_attachedController = null; _attachedController = null;
} }
...@@ -593,6 +597,10 @@ class _DraggableSheetExtent { ...@@ -593,6 +597,10 @@ class _DraggableSheetExtent {
return size / maxSize * availablePixels; return size / maxSize * availablePixels;
} }
void dispose() {
_currentSize.dispose();
}
_DraggableSheetExtent copyWith({ _DraggableSheetExtent copyWith({
required double minSize, required double minSize,
required double maxSize, required double maxSize,
...@@ -663,6 +671,10 @@ class _DraggableScrollableSheetState extends State<DraggableScrollableSheet> { ...@@ -663,6 +671,10 @@ class _DraggableScrollableSheetState extends State<DraggableScrollableSheet> {
@override @override
void didUpdateWidget(covariant DraggableScrollableSheet oldWidget) { void didUpdateWidget(covariant DraggableScrollableSheet oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
if (widget.controller != oldWidget.controller) {
oldWidget.controller?._detach();
widget.controller?._attach(_scrollController);
}
_replaceExtent(oldWidget); _replaceExtent(oldWidget);
} }
...@@ -695,14 +707,14 @@ class _DraggableScrollableSheetState extends State<DraggableScrollableSheet> { ...@@ -695,14 +707,14 @@ class _DraggableScrollableSheetState extends State<DraggableScrollableSheet> {
@override @override
void dispose() { void dispose() {
widget.controller?._detach(); widget.controller?._detach(disposeExtent: true);
_scrollController.dispose(); _scrollController.dispose();
super.dispose(); super.dispose();
} }
void _replaceExtent(covariant DraggableScrollableSheet oldWidget) { void _replaceExtent(covariant DraggableScrollableSheet oldWidget) {
final _DraggableSheetExtent previousExtent = _extent; final _DraggableSheetExtent previousExtent = _extent;
_extent = _extent.copyWith( _extent = previousExtent.copyWith(
minSize: widget.minChildSize, minSize: widget.minChildSize,
maxSize: widget.maxChildSize, maxSize: widget.maxChildSize,
snap: widget.snap, snap: widget.snap,
...@@ -716,6 +728,7 @@ class _DraggableScrollableSheetState extends State<DraggableScrollableSheet> { ...@@ -716,6 +728,7 @@ class _DraggableScrollableSheetState extends State<DraggableScrollableSheet> {
// If an external facing controller was provided, let it know that the // If an external facing controller was provided, let it know that the
// extent has been replaced. // extent has been replaced.
widget.controller?._onExtentReplaced(previousExtent); widget.controller?._onExtentReplaced(previousExtent);
previousExtent.dispose();
if (widget.snap if (widget.snap
&& (widget.snap != oldWidget.snap || widget.snapSizes != oldWidget.snapSizes) && (widget.snap != oldWidget.snap || widget.snapSizes != oldWidget.snapSizes)
&& _scrollController.hasClients && _scrollController.hasClients
......
...@@ -1512,4 +1512,62 @@ void main() { ...@@ -1512,4 +1512,62 @@ void main() {
// DraggableScrollableSheet has rebuilt, so expect the builder to be called. // DraggableScrollableSheet has rebuilt, so expect the builder to be called.
expect(buildCount, 2); expect(buildCount, 2);
}); });
testWidgets('DraggableScrollableSheet controller can be changed', (WidgetTester tester) async {
final DraggableScrollableController controller1 = DraggableScrollableController();
final DraggableScrollableController controller2 = DraggableScrollableController();
final List<double> loggedSizes = <double>[];
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);
controller1.addListener(() {
loggedSizes.add(controller1.size);
});
controller1.jumpTo(0.5);
expect(loggedSizes, <double>[0.5].map((double v) => closeTo(v, precisionErrorTolerance)));
loggedSizes.clear();
await tester.tap(find.text('Switch controller'));
await tester.pump();
expect(controller1.isAttached, false);
expect(controller2.isAttached, true);
controller2.addListener(() {
loggedSizes.add(controller2.size);
});
controller2.jumpTo(1.0);
expect(loggedSizes, <double>[1.0].map((double v) => closeTo(v, precisionErrorTolerance)));
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment