mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Update StretchingOverscrollIndicator for reversed scrollables (#89242)
* Update overscroll indicator for reverse * Review feedback * Review feedback
This commit is contained in:
parent
e127477146
commit
e92f7cd8fe
@ -708,6 +708,28 @@ class _StretchingOverscrollIndicatorState extends State<StretchingOverscrollIndi
|
||||
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
|
||||
void dispose() {
|
||||
_stretchController.dispose();
|
||||
@ -724,23 +746,20 @@ class _StretchingOverscrollIndicatorState extends State<StretchingOverscrollIndi
|
||||
final double stretch = _stretchController.value;
|
||||
double x = 1.0;
|
||||
double y = 1.0;
|
||||
final AlignmentDirectional alignment;
|
||||
|
||||
switch (widget.axis) {
|
||||
case Axis.horizontal:
|
||||
x += stretch;
|
||||
alignment = (_lastOverscrollNotification?.overscroll ?? 0) > 0
|
||||
? AlignmentDirectional.centerEnd
|
||||
: AlignmentDirectional.centerStart;
|
||||
break;
|
||||
case Axis.vertical:
|
||||
y += stretch;
|
||||
alignment = (_lastOverscrollNotification?.overscroll ?? 0) > 0
|
||||
? AlignmentDirectional.bottomCenter
|
||||
: AlignmentDirectional.topCenter;
|
||||
break;
|
||||
}
|
||||
|
||||
final AlignmentDirectional alignment = _getAlignmentForAxisDirection(
|
||||
_lastOverscrollNotification?.overscroll ?? 0.0
|
||||
);
|
||||
|
||||
return Transform(
|
||||
alignment: alignment,
|
||||
transform: Matrix4.diagonal3Values(x, y, 1.0),
|
||||
|
@ -16,16 +16,28 @@ void main() {
|
||||
Key box2Key,
|
||||
Key box3Key,
|
||||
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(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: ScrollConfiguration(
|
||||
behavior: const ScrollBehavior().copyWith(overscroll: false),
|
||||
child: StretchingOverscrollIndicator(
|
||||
axisDirection: axis == null ? AxisDirection.down : AxisDirection.right,
|
||||
axisDirection: axisDirection,
|
||||
child: CustomScrollView(
|
||||
scrollDirection: axis ?? Axis.vertical,
|
||||
reverse: reverse,
|
||||
scrollDirection: axis,
|
||||
controller: controller,
|
||||
slivers: <Widget>[
|
||||
SliverToBoxAdapter(child: Container(
|
||||
@ -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 {
|
||||
final Key box1Key = UniqueKey();
|
||||
final Key box2Key = UniqueKey();
|
||||
|
Loading…
Reference in New Issue
Block a user