Unverified Commit e92f7cd8 authored by Kate Lovett's avatar Kate Lovett Committed by GitHub

Update StretchingOverscrollIndicator for reversed scrollables (#89242)

* Update overscroll indicator for reverse

* Review feedback

* Review feedback
parent e1274771
...@@ -708,6 +708,28 @@ class _StretchingOverscrollIndicatorState extends State<StretchingOverscrollIndi ...@@ -708,6 +708,28 @@ class _StretchingOverscrollIndicatorState extends State<StretchingOverscrollIndi
return false; return false;
} }
AlignmentDirectional _getAlignmentForAxisDirection(double overscroll) {
// Accounts for reversed scrollables by checking the AxisDirection
switch (widget.axisDirection) {
case AxisDirection.up:
return overscroll > 0
? AlignmentDirectional.topCenter
: AlignmentDirectional.bottomCenter;
case AxisDirection.right:
return overscroll > 0
? AlignmentDirectional.centerEnd
: AlignmentDirectional.centerStart;
case AxisDirection.down:
return overscroll > 0
? AlignmentDirectional.bottomCenter
: AlignmentDirectional.topCenter;
case AxisDirection.left:
return overscroll > 0
? AlignmentDirectional.centerStart
: AlignmentDirectional.centerEnd;
}
}
@override @override
void dispose() { void dispose() {
_stretchController.dispose(); _stretchController.dispose();
...@@ -724,23 +746,20 @@ class _StretchingOverscrollIndicatorState extends State<StretchingOverscrollIndi ...@@ -724,23 +746,20 @@ class _StretchingOverscrollIndicatorState extends State<StretchingOverscrollIndi
final double stretch = _stretchController.value; final double stretch = _stretchController.value;
double x = 1.0; double x = 1.0;
double y = 1.0; double y = 1.0;
final AlignmentDirectional alignment;
switch (widget.axis) { switch (widget.axis) {
case Axis.horizontal: case Axis.horizontal:
x += stretch; x += stretch;
alignment = (_lastOverscrollNotification?.overscroll ?? 0) > 0
? AlignmentDirectional.centerEnd
: AlignmentDirectional.centerStart;
break; break;
case Axis.vertical: case Axis.vertical:
y += stretch; y += stretch;
alignment = (_lastOverscrollNotification?.overscroll ?? 0) > 0
? AlignmentDirectional.bottomCenter
: AlignmentDirectional.topCenter;
break; break;
} }
final AlignmentDirectional alignment = _getAlignmentForAxisDirection(
_lastOverscrollNotification?.overscroll ?? 0.0
);
return Transform( return Transform(
alignment: alignment, alignment: alignment,
transform: Matrix4.diagonal3Values(x, y, 1.0), transform: Matrix4.diagonal3Values(x, y, 1.0),
......
...@@ -16,16 +16,28 @@ void main() { ...@@ -16,16 +16,28 @@ void main() {
Key box2Key, Key box2Key,
Key box3Key, Key box3Key,
ScrollController controller, { ScrollController controller, {
Axis? axis, Axis axis = Axis.vertical,
bool reverse = false,
}) { }) {
final AxisDirection axisDirection;
switch (axis) {
case Axis.horizontal:
axisDirection = reverse ? AxisDirection.left : AxisDirection.right;
break;
case Axis.vertical:
axisDirection = reverse ? AxisDirection.up : AxisDirection.down;
break;
}
return Directionality( return Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: ScrollConfiguration( child: ScrollConfiguration(
behavior: const ScrollBehavior().copyWith(overscroll: false), behavior: const ScrollBehavior().copyWith(overscroll: false),
child: StretchingOverscrollIndicator( child: StretchingOverscrollIndicator(
axisDirection: axis == null ? AxisDirection.down : AxisDirection.right, axisDirection: axisDirection,
child: CustomScrollView( child: CustomScrollView(
scrollDirection: axis ?? Axis.vertical, reverse: reverse,
scrollDirection: axis,
controller: controller, controller: controller,
slivers: <Widget>[ slivers: <Widget>[
SliverToBoxAdapter(child: Container( SliverToBoxAdapter(child: Container(
...@@ -118,6 +130,79 @@ void main() { ...@@ -118,6 +130,79 @@ void main() {
); );
}); });
testWidgets('Stretch overscroll works in reverse - vertical', (WidgetTester tester) async {
final Key box1Key = UniqueKey();
final Key box2Key = UniqueKey();
final Key box3Key = UniqueKey();
final ScrollController controller = ScrollController();
await tester.pumpWidget(
buildTest(box1Key, box2Key, box3Key, controller, reverse: true),
);
expect(find.byType(StretchingOverscrollIndicator), findsOneWidget);
expect(find.byType(GlowingOverscrollIndicator), findsNothing);
final RenderBox box1 = tester.renderObject(find.byKey(box1Key));
final RenderBox box2 = tester.renderObject(find.byKey(box2Key));
final RenderBox box3 = tester.renderObject(find.byKey(box3Key));
expect(controller.offset, 0.0);
expect(box1.localToGlobal(Offset.zero), const Offset(0.0, 350.0));
expect(box2.localToGlobal(Offset.zero), const Offset(0.0, 100.0));
expect(box3.localToGlobal(Offset.zero), const Offset(0.0, -150.0));
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(CustomScrollView)));
// Overscroll
await gesture.moveBy(const Offset(0.0, -200.0));
await tester.pumpAndSettle();
expect(box1.localToGlobal(Offset.zero).dy, lessThan(350.0));
expect(box2.localToGlobal(Offset.zero).dy, lessThan(100.0));
expect(box3.localToGlobal(Offset.zero).dy, lessThan(-150.0));
await expectLater(
find.byType(CustomScrollView),
matchesGoldenFile('overscroll_stretch.vertical.reverse.png'),
);
});
testWidgets('Stretch overscroll horizontally', (WidgetTester tester) async {
final Key box1Key = UniqueKey();
final Key box2Key = UniqueKey();
final Key box3Key = UniqueKey();
final ScrollController controller = ScrollController();
await tester.pumpWidget(
buildTest(
box1Key,
box2Key,
box3Key,
controller,
axis: Axis.horizontal,
reverse: true,
),
);
expect(find.byType(StretchingOverscrollIndicator), findsOneWidget);
expect(find.byType(GlowingOverscrollIndicator), findsNothing);
final RenderBox box1 = tester.renderObject(find.byKey(box1Key));
final RenderBox box2 = tester.renderObject(find.byKey(box2Key));
final RenderBox box3 = tester.renderObject(find.byKey(box3Key));
expect(controller.offset, 0.0);
expect(box1.localToGlobal(Offset.zero), const Offset(500.0, 0.0));
expect(box2.localToGlobal(Offset.zero), const Offset(200.0, 0.0));
expect(box3.localToGlobal(Offset.zero), const Offset(-100.0, 0.0));
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(CustomScrollView)));
// Overscroll
await gesture.moveBy(const Offset(200.0, 0.0));
await tester.pumpAndSettle();
expect(box1.localToGlobal(Offset.zero).dx, greaterThan(500.0));
expect(box2.localToGlobal(Offset.zero).dx, greaterThan(200.0));
expect(box3.localToGlobal(Offset.zero).dx, greaterThan(-100.0));
await expectLater(
find.byType(CustomScrollView),
matchesGoldenFile('overscroll_stretch.horizontal.reverse.png'),
);
});
testWidgets('Stretch overscroll horizontally', (WidgetTester tester) async { testWidgets('Stretch overscroll horizontally', (WidgetTester tester) async {
final Key box1Key = UniqueKey(); final Key box1Key = UniqueKey();
final Key box2Key = UniqueKey(); final Key box2Key = UniqueKey();
......
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