Skip to content

Commit a3eeb51

Browse files
itomednfield
authored andcommitted
Fix draggable scrollable sheet scroll notification (flutter#45083)
1 parent 5fb790e commit a3eeb51

File tree

2 files changed

+58
-8
lines changed

2 files changed

+58
-8
lines changed

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

+2
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,8 @@ class _DraggableScrollableSheetScrollPosition
490490
velocity = ballisticController.velocity + (physics.tolerance.velocity * ballisticController.velocity.sign);
491491
super.goBallistic(velocity);
492492
ballisticController.stop();
493+
} else if (ballisticController.isCompleted) {
494+
super.goBallistic(0);
493495
}
494496
}
495497

packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart

+56-8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ void main() {
1515
double minChildSize = .25,
1616
double itemExtent,
1717
Key containerKey,
18+
NotificationListenerCallback<ScrollNotification> onScrollNotification,
1819
}) {
1920
return Directionality(
2021
textDirection: TextDirection.ltr,
@@ -29,14 +30,17 @@ void main() {
2930
minChildSize: minChildSize,
3031
initialChildSize: initialChildSize,
3132
builder: (BuildContext context, ScrollController scrollController) {
32-
return Container(
33-
key: containerKey,
34-
color: const Color(0xFFABCDEF),
35-
child: ListView.builder(
36-
controller: scrollController,
37-
itemExtent: itemExtent,
38-
itemCount: itemCount,
39-
itemBuilder: (BuildContext context, int index) => Text('Item $index'),
33+
return NotificationListener<ScrollNotification>(
34+
onNotification: onScrollNotification,
35+
child: Container(
36+
key: containerKey,
37+
color: const Color(0xFFABCDEF),
38+
child: ListView.builder(
39+
controller: scrollController,
40+
itemExtent: itemExtent,
41+
itemCount: itemCount,
42+
itemBuilder: (BuildContext context, int index) => Text('Item $index'),
43+
),
4044
),
4145
);
4246
},
@@ -260,5 +264,49 @@ void main() {
260264

261265
debugDefaultTargetPlatformOverride = null;
262266
});
267+
268+
testWidgets('ScrollNotification correctly dispatched when flung without covering its container', (WidgetTester tester) async {
269+
final List<Type> notificationTypes = <Type>[];
270+
await tester.pumpWidget(_boilerplate(
271+
null,
272+
onScrollNotification: (ScrollNotification notification) {
273+
notificationTypes.add(notification.runtimeType);
274+
return false;
275+
},
276+
));
277+
278+
await tester.fling(find.text('Item 1'), const Offset(0, -200), 200);
279+
await tester.pumpAndSettle();
280+
281+
// TODO(itome): Make sure UserScrollNotification and ScrollUpdateNotification are called correctly.
282+
final List<Type> types = <Type>[
283+
ScrollStartNotification,
284+
ScrollEndNotification,
285+
];
286+
expect(notificationTypes, equals(types));
287+
});
288+
289+
testWidgets('ScrollNotification correctly dispatched when flung with contents scroll', (WidgetTester tester) async {
290+
final List<Type> notificationTypes = <Type>[];
291+
await tester.pumpWidget(_boilerplate(
292+
null,
293+
onScrollNotification: (ScrollNotification notification) {
294+
notificationTypes.add(notification.runtimeType);
295+
return false;
296+
},
297+
));
298+
299+
await tester.flingFrom(const Offset(0, 325), const Offset(0, -325), 200);
300+
await tester.pumpAndSettle();
301+
302+
final List<Type> types = <Type>[
303+
ScrollStartNotification,
304+
UserScrollNotification,
305+
...List<Type>.filled(5, ScrollUpdateNotification),
306+
ScrollEndNotification,
307+
UserScrollNotification,
308+
];
309+
expect(notificationTypes, types);
310+
});
263311
}
264312
}

0 commit comments

Comments
 (0)