Unverified Commit a30d816a authored by youssef ali's avatar youssef ali Committed by GitHub

fix stretch effect with rtl support (#113214)

parent e76f8831
......@@ -744,7 +744,7 @@ class _StretchingOverscrollIndicatorState extends State<StretchingOverscrollIndi
return false;
}
AlignmentDirectional _getAlignmentForAxisDirection(double overscroll) {
AlignmentGeometry _getAlignmentForAxisDirection(double overscroll) {
// Accounts for reversed scrollables by checking the AxisDirection
switch (widget.axisDirection) {
case AxisDirection.up:
......@@ -753,16 +753,16 @@ class _StretchingOverscrollIndicatorState extends State<StretchingOverscrollIndi
: AlignmentDirectional.bottomCenter;
case AxisDirection.right:
return overscroll > 0
? AlignmentDirectional.centerEnd
: AlignmentDirectional.centerStart;
? Alignment.centerRight
: Alignment.centerLeft;
case AxisDirection.down:
return overscroll > 0
? AlignmentDirectional.bottomCenter
: AlignmentDirectional.topCenter;
case AxisDirection.left:
return overscroll > 0
? AlignmentDirectional.centerStart
: AlignmentDirectional.centerEnd;
? Alignment.centerLeft
: Alignment.centerRight;
}
}
......@@ -796,7 +796,7 @@ class _StretchingOverscrollIndicatorState extends State<StretchingOverscrollIndi
break;
}
final AlignmentDirectional alignment = _getAlignmentForAxisDirection(
final AlignmentGeometry alignment = _getAlignmentForAxisDirection(
_lastOverscrollNotification?.overscroll ?? 0.0
);
......
......@@ -18,11 +18,16 @@ void main() {
ScrollController controller, {
Axis axis = Axis.vertical,
bool reverse = false,
TextDirection textDirection = TextDirection.ltr,
}) {
final AxisDirection axisDirection;
switch (axis) {
case Axis.horizontal:
axisDirection = reverse ? AxisDirection.left : AxisDirection.right;
if (textDirection == TextDirection.rtl) {
axisDirection = reverse ? AxisDirection.right : AxisDirection.left;
} else {
axisDirection = reverse ? AxisDirection.left : AxisDirection.right;
}
break;
case Axis.vertical:
axisDirection = reverse ? AxisDirection.up : AxisDirection.down;
......@@ -30,7 +35,7 @@ void main() {
}
return Directionality(
textDirection: TextDirection.ltr,
textDirection: textDirection,
child: MediaQuery(
data: const MediaQueryData(size: Size(800.0, 600.0)),
child: ScrollConfiguration(
......@@ -218,6 +223,92 @@ void main() {
);
});
testWidgets('Stretch overscroll works in reverse - horizontal - RTL', (WidgetTester tester) async {
final GlobalKey box1Key = GlobalKey();
final GlobalKey box2Key = GlobalKey();
final GlobalKey box3Key = GlobalKey();
final ScrollController controller = ScrollController();
await tester.pumpWidget(
buildTest(
box1Key,
box2Key,
box3Key,
controller,
axis: Axis.horizontal,
reverse: true,
textDirection: TextDirection.rtl,
)
);
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), Offset.zero);
expect(box2.localToGlobal(Offset.zero), const Offset(300.0, 0.0));
expect(box3.localToGlobal(Offset.zero), const Offset(600.0, 0.0));
await expectLater(
find.byType(CustomScrollView),
matchesGoldenFile('overscroll_stretch.horizontal.reverse.rtl.start.png'),
);
TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(CustomScrollView)));
// Overscroll the start
await gesture.moveBy(const Offset(200.0, 0.0));
await tester.pumpAndSettle();
expect(box1.localToGlobal(Offset.zero), Offset.zero);
expect(box2.localToGlobal(Offset.zero).dx, greaterThan(305.0));
expect(box3.localToGlobal(Offset.zero).dx, greaterThan(610.0));
await expectLater(
find.byType(CustomScrollView),
matchesGoldenFile('overscroll_stretch.horizontal.reverse.rtl.start.stretched.png'),
);
await gesture.up();
await tester.pumpAndSettle();
// Stretch released back to the start
expect(box1.localToGlobal(Offset.zero), Offset.zero);
expect(box2.localToGlobal(Offset.zero), const Offset(300.0, 0.0));
expect(box3.localToGlobal(Offset.zero), const Offset(600.0, 0.0));
// Jump to end of the list
controller.jumpTo(controller.position.maxScrollExtent);
await tester.pumpAndSettle();
expect(controller.offset, 100.0);
expect(box1.localToGlobal(Offset.zero).dx, -100.0);
expect(box2.localToGlobal(Offset.zero).dx, 200.0);
expect(box3.localToGlobal(Offset.zero).dx, 500.0);
await expectLater(
find.byType(CustomScrollView),
matchesGoldenFile('overscroll_stretch.horizontal.reverse.rtl.end.png'),
);
gesture = await tester.startGesture(tester.getCenter(find.byType(CustomScrollView)));
// Overscroll the end
await gesture.moveBy(const Offset(-200.0, 0.0));
await tester.pumpAndSettle();
expect(box1.localToGlobal(Offset.zero).dx, lessThan(-116.0));
expect(box2.localToGlobal(Offset.zero).dx, lessThan(190.0));
expect(box3.localToGlobal(Offset.zero).dx, lessThan(500.0));
await expectLater(
find.byType(CustomScrollView),
matchesGoldenFile('overscroll_stretch.horizontal.reverse.rtl.end.stretched.png'),
);
await gesture.up();
await tester.pumpAndSettle();
// Stretch released back
expect(box1.localToGlobal(Offset.zero).dx, -100.0);
expect(box2.localToGlobal(Offset.zero).dx, 200.0);
expect(box3.localToGlobal(Offset.zero).dx, 500.0);
});
testWidgets('Stretch overscroll horizontally', (WidgetTester tester) async {
final GlobalKey box1Key = GlobalKey();
final GlobalKey box2Key = GlobalKey();
......@@ -295,6 +386,46 @@ void main() {
expect(box3.localToGlobal(Offset.zero).dx, 500.0);
});
testWidgets('Stretch overscroll horizontally RTl', (WidgetTester tester) async {
final GlobalKey box1Key = GlobalKey();
final GlobalKey box2Key = GlobalKey();
final GlobalKey box3Key = GlobalKey();
final ScrollController controller = ScrollController();
await tester.pumpWidget(
buildTest(
box1Key,
box2Key,
box3Key,
controller,
axis: Axis.horizontal,
textDirection: TextDirection.rtl,
)
);
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, lessThan(500.0));
expect(box2.localToGlobal(Offset.zero).dx, lessThan(200.0));
expect(box3.localToGlobal(Offset.zero).dx, lessThan(-100.0));
await expectLater(
find.byType(CustomScrollView),
matchesGoldenFile('overscroll_stretch.horizontal.rtl.png'),
);
});
testWidgets('Disallow stretching overscroll', (WidgetTester tester) async {
final GlobalKey box1Key = GlobalKey();
final GlobalKey box2Key = GlobalKey();
......
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