[CupertinoActionSheet] Fix overflow of the overscroll section when the user scrolls far (#149542)
When I implemented https://github.com/flutter/flutter/pull/149334, there was a bug that if the actions section is overscrolled for too far (typically due to a fling), the overscroll background might be so long that it overflows the actions section. This PR fixes this bug.
This commit is contained in:
parent
e02d29d52e
commit
691a18df5f
@ -964,8 +964,16 @@ class _ActionSheetMainSheetState extends State<_ActionSheetMainSheet> {
|
|||||||
bool _onScrollUpdate(ScrollUpdateNotification notification) {
|
bool _onScrollUpdate(ScrollUpdateNotification notification) {
|
||||||
final ScrollMetrics metrics = notification.metrics;
|
final ScrollMetrics metrics = notification.metrics;
|
||||||
setState(() {
|
setState(() {
|
||||||
_topOverscroll = math.max(metrics.minScrollExtent - metrics.pixels, 0);
|
// The sizes of the overscroll should not be longer than the height of the
|
||||||
_bottomOverscroll = math.max(metrics.pixels - metrics.maxScrollExtent, 0);
|
// actions section.
|
||||||
|
_topOverscroll = math.min(
|
||||||
|
math.max(metrics.minScrollExtent - metrics.pixels, 0),
|
||||||
|
metrics.viewportDimension,
|
||||||
|
);
|
||||||
|
_bottomOverscroll = math.min(
|
||||||
|
math.max(metrics.pixels - metrics.maxScrollExtent, 0),
|
||||||
|
metrics.viewportDimension,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -489,6 +489,48 @@ void main() {
|
|||||||
await gesture.up();
|
await gesture.up();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('Actions section correctly renders overscrolls with very far scrolls', (WidgetTester tester) async {
|
||||||
|
// When the scroll is really far, the overscroll might be longer than the
|
||||||
|
// actions section, causing overflow if not controlled.
|
||||||
|
final ScrollController actionScrollController = ScrollController();
|
||||||
|
addTearDown(actionScrollController.dispose);
|
||||||
|
await tester.pumpWidget(
|
||||||
|
createAppWithButtonThatLaunchesActionSheet(
|
||||||
|
Builder(builder: (BuildContext context) {
|
||||||
|
return CupertinoActionSheet(
|
||||||
|
message: Text('message' * 300),
|
||||||
|
actions: List<Widget>.generate(4, (int i) =>
|
||||||
|
CupertinoActionSheetAction(
|
||||||
|
onPressed: () {},
|
||||||
|
child: Text('Button $i'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await tester.tap(find.text('Go'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.text('Button 0')));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await gesture.moveBy(const Offset(0, 40)); // A short drag to start the gesture.
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
// The drag is far enough to make the overscroll longer than the section.
|
||||||
|
await gesture.moveBy(const Offset(0, 1000));
|
||||||
|
await tester.pump();
|
||||||
|
// The buttons should be out of the screen
|
||||||
|
expect(
|
||||||
|
tester.getTopLeft(find.text('Button 0')).dy,
|
||||||
|
greaterThan(tester.getBottomLeft(find.byType(CupertinoActionSheet)).dy)
|
||||||
|
);
|
||||||
|
await expectLater(
|
||||||
|
find.byType(CupertinoActionSheet),
|
||||||
|
matchesGoldenFile('cupertinoActionSheet.long-overscroll.0.png'),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('Tap on button calls onPressed', (WidgetTester tester) async {
|
testWidgets('Tap on button calls onPressed', (WidgetTester tester) async {
|
||||||
bool wasPressed = false;
|
bool wasPressed = false;
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user