mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Fix leading overscroll for RenderShrinkWrappingViewport (#87143)
This commit is contained in:
parent
be71266317
commit
daa721f2f0
@ -1924,7 +1924,7 @@ class RenderShrinkWrappingViewport extends RenderViewportBase<SliverLogicalConta
|
||||
child: firstChild,
|
||||
scrollOffset: math.max(0.0, correctedOffset),
|
||||
overlap: math.min(0.0, correctedOffset),
|
||||
layoutOffset: 0.0,
|
||||
layoutOffset: math.max(0.0, -correctedOffset),
|
||||
remainingPaintExtent: mainAxisExtent,
|
||||
mainAxisExtent: mainAxisExtent,
|
||||
crossAxisExtent: crossAxisExtent,
|
||||
|
||||
@ -1843,6 +1843,188 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
Widget _buildShrinkWrap({
|
||||
ScrollController? controller,
|
||||
Axis scrollDirection = Axis.vertical,
|
||||
ScrollPhysics? physics,
|
||||
}) {
|
||||
return Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: MediaQuery(
|
||||
data: const MediaQueryData(),
|
||||
child: ListView.builder(
|
||||
controller: controller,
|
||||
physics: physics,
|
||||
scrollDirection: scrollDirection,
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (BuildContext context, int index) => SizedBox(height: 50, width: 50, child: Text('Item $index')),
|
||||
itemCount: 20,
|
||||
itemExtent: 50,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Shrinkwrap allows overscrolling on default platforms - vertical', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/10949
|
||||
// Scrollables should overscroll by default on iOS and macOS
|
||||
final ScrollController controller = ScrollController();
|
||||
await tester.pumpWidget(
|
||||
_buildShrinkWrap(controller: controller),
|
||||
);
|
||||
expect(controller.offset, 0.0);
|
||||
expect(tester.getTopLeft(find.text('Item 0')).dy, 0.0);
|
||||
// Check overscroll at both ends
|
||||
// Start
|
||||
TestGesture overscrollGesture = await tester.startGesture(tester.getCenter(find.byType(ListView)));
|
||||
await overscrollGesture.moveBy(const Offset(0, 25));
|
||||
await tester.pump();
|
||||
expect(controller.offset, -25.0);
|
||||
expect(tester.getTopLeft(find.text('Item 0')).dy, 25.0);
|
||||
await overscrollGesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
expect(controller.offset, 0.0);
|
||||
expect(tester.getTopLeft(find.text('Item 0')).dy, 0.0);
|
||||
|
||||
// End
|
||||
final double maxExtent = controller.position.maxScrollExtent;
|
||||
controller.jumpTo(controller.position.maxScrollExtent);
|
||||
await tester.pumpAndSettle();
|
||||
expect(controller.offset, maxExtent);
|
||||
expect(tester.getBottomLeft(find.text('Item 19')).dy, 400.0);
|
||||
|
||||
overscrollGesture = await tester.startGesture(tester.getCenter(find.byType(ListView)));
|
||||
await overscrollGesture.moveBy(const Offset(0, -25));
|
||||
await tester.pump();
|
||||
expect(controller.offset, greaterThan(maxExtent));
|
||||
expect(tester.getBottomLeft(find.text('Item 19')).dy, 375.0);
|
||||
await overscrollGesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
expect(controller.offset, maxExtent);
|
||||
expect(tester.getBottomLeft(find.text('Item 19')).dy, 400.0);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('Shrinkwrap allows overscrolling on default platforms - horizontal', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/10949
|
||||
// Scrollables should overscroll by default on iOS and macOS
|
||||
final ScrollController controller = ScrollController();
|
||||
await tester.pumpWidget(
|
||||
_buildShrinkWrap(controller: controller, scrollDirection: Axis.horizontal),
|
||||
);
|
||||
expect(controller.offset, 0.0);
|
||||
expect(tester.getTopLeft(find.text('Item 0')).dx, 0.0);
|
||||
// Check overscroll at both ends
|
||||
// Start
|
||||
TestGesture overscrollGesture = await tester.startGesture(tester.getCenter(find.byType(ListView)));
|
||||
await overscrollGesture.moveBy(const Offset(25, 0));
|
||||
await tester.pump();
|
||||
expect(controller.offset, -25.0);
|
||||
expect(tester.getTopLeft(find.text('Item 0')).dx, 25.0);
|
||||
await overscrollGesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
expect(controller.offset, 0.0);
|
||||
expect(tester.getTopLeft(find.text('Item 0')).dx, 0.0);
|
||||
|
||||
// End
|
||||
final double maxExtent = controller.position.maxScrollExtent;
|
||||
controller.jumpTo(controller.position.maxScrollExtent);
|
||||
await tester.pumpAndSettle();
|
||||
expect(controller.offset, maxExtent);
|
||||
expect(tester.getTopRight(find.text('Item 19')).dx, 400.0);
|
||||
|
||||
overscrollGesture = await tester.startGesture(tester.getCenter(find.byType(ListView)));
|
||||
await overscrollGesture.moveBy(const Offset(-25, 0));
|
||||
await tester.pump();
|
||||
expect(controller.offset, greaterThan(maxExtent));
|
||||
expect(tester.getTopRight(find.text('Item 19')).dx, 375.0);
|
||||
await overscrollGesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
expect(controller.offset, maxExtent);
|
||||
expect(tester.getTopRight(find.text('Item 19')).dx, 400.0);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('Shrinkwrap allows overscrolling per physics - vertical', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/10949
|
||||
// Scrollables should overscroll when the scroll physics allow
|
||||
final ScrollController controller = ScrollController();
|
||||
await tester.pumpWidget(
|
||||
_buildShrinkWrap(controller: controller, physics: const BouncingScrollPhysics()),
|
||||
);
|
||||
expect(controller.offset, 0.0);
|
||||
expect(tester.getTopLeft(find.text('Item 0')).dy, 0.0);
|
||||
// Check overscroll at both ends
|
||||
// Start
|
||||
TestGesture overscrollGesture = await tester.startGesture(tester.getCenter(find.byType(ListView)));
|
||||
await overscrollGesture.moveBy(const Offset(0, 25));
|
||||
await tester.pump();
|
||||
expect(controller.offset, -25.0);
|
||||
expect(tester.getTopLeft(find.text('Item 0')).dy, 25.0);
|
||||
await overscrollGesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
expect(controller.offset, 0.0);
|
||||
expect(tester.getTopLeft(find.text('Item 0')).dy, 0.0);
|
||||
|
||||
// End
|
||||
final double maxExtent = controller.position.maxScrollExtent;
|
||||
controller.jumpTo(controller.position.maxScrollExtent);
|
||||
await tester.pumpAndSettle();
|
||||
expect(controller.offset, maxExtent);
|
||||
expect(tester.getBottomLeft(find.text('Item 19')).dy, 400.0);
|
||||
|
||||
overscrollGesture = await tester.startGesture(tester.getCenter(find.byType(ListView)));
|
||||
await overscrollGesture.moveBy(const Offset(0, -25));
|
||||
await tester.pump();
|
||||
expect(controller.offset, greaterThan(maxExtent));
|
||||
expect(tester.getBottomLeft(find.text('Item 19')).dy, 375.0);
|
||||
await overscrollGesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
expect(controller.offset, maxExtent);
|
||||
expect(tester.getBottomLeft(find.text('Item 19')).dy, 400.0);
|
||||
});
|
||||
|
||||
testWidgets('Shrinkwrap allows overscrolling per physics - horizontal', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/10949
|
||||
// Scrollables should overscroll when the scroll physics allow
|
||||
final ScrollController controller = ScrollController();
|
||||
await tester.pumpWidget(
|
||||
_buildShrinkWrap(
|
||||
controller: controller,
|
||||
scrollDirection: Axis.horizontal,
|
||||
physics: const BouncingScrollPhysics(),
|
||||
),
|
||||
);
|
||||
expect(controller.offset, 0.0);
|
||||
expect(tester.getTopLeft(find.text('Item 0')).dx, 0.0);
|
||||
// Check overscroll at both ends
|
||||
// Start
|
||||
TestGesture overscrollGesture = await tester.startGesture(tester.getCenter(find.byType(ListView)));
|
||||
await overscrollGesture.moveBy(const Offset(25, 0));
|
||||
await tester.pump();
|
||||
expect(controller.offset, -25.0);
|
||||
expect(tester.getTopLeft(find.text('Item 0')).dx, 25.0);
|
||||
await overscrollGesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
expect(controller.offset, 0.0);
|
||||
expect(tester.getTopLeft(find.text('Item 0')).dx, 0.0);
|
||||
|
||||
// End
|
||||
final double maxExtent = controller.position.maxScrollExtent;
|
||||
controller.jumpTo(controller.position.maxScrollExtent);
|
||||
await tester.pumpAndSettle();
|
||||
expect(controller.offset, maxExtent);
|
||||
expect(tester.getTopRight(find.text('Item 19')).dx, 400.0);
|
||||
|
||||
overscrollGesture = await tester.startGesture(tester.getCenter(find.byType(ListView)));
|
||||
await overscrollGesture.moveBy(const Offset(-25, 0));
|
||||
await tester.pump();
|
||||
expect(controller.offset, greaterThan(maxExtent));
|
||||
expect(tester.getTopRight(find.text('Item 19')).dx, 375.0);
|
||||
await overscrollGesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
expect(controller.offset, maxExtent);
|
||||
expect(tester.getTopRight(find.text('Item 19')).dx, 400.0);
|
||||
});
|
||||
|
||||
testWidgets('Handles infinite constraints when TargetPlatform is iOS or macOS', (WidgetTester tester) async {
|
||||
// regression test for https://github.com/flutter/flutter/issues/45866
|
||||
await tester.pumpWidget(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user