Skip to content

Commit 6efdf0a

Browse files
authored
fix a _DraggableScrollableSheetScrollPosition update bug (#103328)
1 parent 9f856ac commit 6efdf0a

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,21 @@ class _DraggableScrollableSheetScrollPosition extends ScrollPositionWithSingleCo
810810

811811
_DraggableSheetExtent get extent => getExtent();
812812

813+
@override
814+
void absorb(ScrollPosition other) {
815+
super.absorb(other);
816+
assert(_dragCancelCallback == null);
817+
818+
if (other is! _DraggableScrollableSheetScrollPosition) {
819+
return;
820+
}
821+
822+
if (other._dragCancelCallback != null) {
823+
_dragCancelCallback = other._dragCancelCallback;
824+
other._dragCancelCallback = null;
825+
}
826+
}
827+
813828
@override
814829
void beginActivity(ScrollActivity? newActivity) {
815830
// Cancel the running ballistic simulations

packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,54 @@ void main() {
6363
);
6464
}
6565

66+
testWidgets('Do not crash when replacing scroll position during the drag', (WidgetTester tester) async {
67+
// Regression test for https://github.com/flutter/flutter/issues/89681
68+
bool showScrollbars = false;
69+
await tester.pumpWidget(
70+
Directionality(
71+
textDirection: TextDirection.ltr,
72+
child: MediaQuery(
73+
data: const MediaQueryData(),
74+
child: Align(
75+
alignment: Alignment.bottomCenter,
76+
child: DraggableScrollableSheet(
77+
initialChildSize: 0.7,
78+
minChildSize: 0.2,
79+
maxChildSize: 0.9,
80+
expand: false,
81+
builder: (BuildContext context, ScrollController scrollController) {
82+
showScrollbars = !showScrollbars;
83+
// Change the scroll behavior will trigger scroll position replace.
84+
final ScrollBehavior behavior = const ScrollBehavior().copyWith(scrollbars: showScrollbars);
85+
return ScrollConfiguration(
86+
behavior: behavior,
87+
child: ListView.separated(
88+
physics: const BouncingScrollPhysics(),
89+
controller: scrollController,
90+
separatorBuilder: (_, __) => const Divider(),
91+
itemCount: 100,
92+
itemBuilder: (_, int index) => SizedBox(
93+
height: 100,
94+
child: ColoredBox(
95+
color: Colors.primaries[index % Colors.primaries.length],
96+
child: Text('Item $index'),
97+
),
98+
),
99+
),
100+
);
101+
},
102+
),
103+
),
104+
),
105+
),
106+
);
107+
108+
await tester.fling(find.text('Item 1'), const Offset(0, 200), 350);
109+
await tester.pumpAndSettle();
110+
111+
// Go without throw.
112+
});
113+
66114
testWidgets('Scrolls correct amount when maxChildSize < 1.0', (WidgetTester tester) async {
67115
const Key key = ValueKey<String>('container');
68116
await tester.pumpWidget(boilerplateWidget(

0 commit comments

Comments
 (0)