216 lines
7.7 KiB
Dart
216 lines
7.7 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'dart:math' as math;
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
void main() {
|
|
testWidgets('Scrollable scaled up', (WidgetTester tester) async {
|
|
final ScrollController controller = ScrollController();
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Transform.scale(
|
|
scale: 2.0,
|
|
child: Center(
|
|
child: SizedBox(
|
|
width: 200,
|
|
child: ListView.builder(
|
|
controller: controller,
|
|
cacheExtent: 0.0,
|
|
itemBuilder: (BuildContext context, int index) {
|
|
return Container(
|
|
height: 100.0,
|
|
color: index.isEven ? Colors.blue : Colors.red,
|
|
child: Text('Tile $index'),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
expect(controller.offset, 0.0);
|
|
|
|
await tester.drag(find.byType(ListView), const Offset(0.0, -100.0));
|
|
await tester.pump();
|
|
expect(controller.offset, 50.0); // 100.0 / 2.0
|
|
|
|
await tester.drag(find.byType(ListView), const Offset(80.0, -70.0));
|
|
await tester.pump();
|
|
expect(controller.offset, 85.0); // 50.0 + (70.0 / 2)
|
|
|
|
await tester.drag(find.byType(ListView), const Offset(100.0, 0.0));
|
|
await tester.pump();
|
|
expect(controller.offset, 85.0);
|
|
|
|
await tester.drag(find.byType(ListView), const Offset(0.0, 85.0));
|
|
await tester.pump();
|
|
expect(controller.offset, 42.5); // 85.0 - (85.0 / 2)
|
|
});
|
|
|
|
testWidgets('Scrollable scaled down', (WidgetTester tester) async {
|
|
final ScrollController controller = ScrollController();
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Transform.scale(
|
|
scale: 0.5,
|
|
child: Center(
|
|
child: SizedBox(
|
|
width: 200,
|
|
child: ListView.builder(
|
|
controller: controller,
|
|
cacheExtent: 0.0,
|
|
itemBuilder: (BuildContext context, int index) {
|
|
return Container(
|
|
height: 100.0,
|
|
color: index.isEven ? Colors.blue : Colors.red,
|
|
child: Text('Tile $index'),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
expect(controller.offset, 0.0);
|
|
|
|
await tester.drag(find.byType(ListView), const Offset(0.0, -100.0));
|
|
await tester.pump();
|
|
expect(controller.offset, 200.0); // 100.0 * 2.0
|
|
|
|
await tester.drag(find.byType(ListView), const Offset(80.0, -70.0));
|
|
await tester.pump();
|
|
expect(controller.offset, 340.0); // 200.0 + (70.0 * 2)
|
|
|
|
await tester.drag(find.byType(ListView), const Offset(100.0, 0.0));
|
|
await tester.pump();
|
|
expect(controller.offset, 340.0);
|
|
|
|
await tester.drag(find.byType(ListView), const Offset(0.0, 170.0));
|
|
await tester.pump();
|
|
expect(controller.offset, 0.0); // 340.0 - (170.0 * 2)
|
|
});
|
|
|
|
testWidgets('Scrollable rotated 90 degrees', (WidgetTester tester) async {
|
|
final ScrollController controller = ScrollController();
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Transform.rotate(
|
|
angle: math.pi / 2,
|
|
child: Center(
|
|
child: SizedBox(
|
|
width: 200,
|
|
child: ListView.builder(
|
|
controller: controller,
|
|
cacheExtent: 0.0,
|
|
itemBuilder: (BuildContext context, int index) {
|
|
return Container(
|
|
height: 100.0,
|
|
color: index.isEven ? Colors.blue : Colors.red,
|
|
child: Text('Tile $index'),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
expect(controller.offset, 0.0);
|
|
|
|
await tester.drag(find.byType(ListView), const Offset(100.0, 0.0));
|
|
await tester.pump();
|
|
expect(controller.offset, 100.0);
|
|
|
|
await tester.drag(find.byType(ListView), const Offset(0.0, -100.0));
|
|
await tester.pump();
|
|
expect(controller.offset, 100.0);
|
|
|
|
await tester.drag(find.byType(ListView), const Offset(-70.0, -50.0));
|
|
await tester.pump();
|
|
expect(controller.offset, 30.0); // 100.0 - 70.0
|
|
});
|
|
|
|
testWidgets('Perspective transform on scrollable', (WidgetTester tester) async {
|
|
final ScrollController controller = ScrollController();
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Transform(
|
|
transform: Matrix4.identity()
|
|
..setEntry(3, 2, 0.001)
|
|
..rotateX(math.pi / 4),
|
|
child: Center(
|
|
child: SizedBox(
|
|
width: 200,
|
|
child: ListView.builder(
|
|
controller: controller,
|
|
cacheExtent: 0.0,
|
|
itemBuilder: (BuildContext context, int index) {
|
|
return Container(
|
|
height: 100.0,
|
|
color: index.isEven ? Colors.blue : Colors.red,
|
|
child: Text('Tile $index'),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
expect(controller.offset, 0.0);
|
|
|
|
// We want to test that the point in the ListView that the finger touches
|
|
// on the screen stays under the finger as the finger scrolls the ListView
|
|
// in vertical direction. For this, we pick a point in the ListView (here
|
|
// the center of Tile 5) and calculate its position in the coordinate space
|
|
// of the screen. We then place our finger on that point and drag that
|
|
// point up in vertical direction. After the scroll activity is done,
|
|
// we verify that - in the coordinate space of the screen (!) - the point
|
|
// has moved the same distance as the finger. Due to the perspective
|
|
// transform the point will have moved more distance in the *local*
|
|
// coordinate system of the ListView.
|
|
|
|
// Calculate where the center of Tile 5 is located in the coordinate
|
|
// space of the screen. We cannot use `tester.getCenter` because it
|
|
// does not properly remove the perspective component from the transform
|
|
// to give us the place on the screen at which we need to touch the screen
|
|
// to have the center of Tile 5 directly under our finger.
|
|
final RenderBox tile5 = tester.renderObject(find.text('Tile 5'));
|
|
final Offset pointOnScreenStart = MatrixUtils.transformPoint(
|
|
PointerEvent.removePerspectiveTransform(tile5.getTransformTo(null)),
|
|
tile5.size.center(Offset.zero),
|
|
);
|
|
|
|
// Place the finger on the tracked point and move the finger upwards for
|
|
// 50 pixels to scroll the ListView (the ListView's scroll offset will
|
|
// move more then 50 pixels due to the perspective transform).
|
|
await tester.dragFrom(pointOnScreenStart, const Offset(0.0, -50.0));
|
|
await tester.pump();
|
|
|
|
// Get the new position of the tracked point in the screen's coordinate
|
|
// system.
|
|
final Offset pointOnScreenEnd = MatrixUtils.transformPoint(
|
|
PointerEvent.removePerspectiveTransform(tile5.getTransformTo(null)),
|
|
tile5.size.center(Offset.zero),
|
|
);
|
|
|
|
// The tracked point (in the coordinate space of the screen) and the finger
|
|
// should have moved the same vertical distance over the screen.
|
|
expect(
|
|
pointOnScreenStart.dy - pointOnScreenEnd.dy,
|
|
within(distance: 0.00001, from: 50.0),
|
|
);
|
|
|
|
// While the point traveled the same distance as the finger in the
|
|
// coordinate space of the screen, the scroll view actually moved far more
|
|
// pixels in its local coordinate system due to the perspective transform.
|
|
expect(controller.offset, greaterThan(100));
|
|
});
|
|
}
|