Merge pull request #1401 from Hixie/lists
Make hit testing work in horizontal scrolling list
This commit is contained in:
commit
4150615e26
@ -589,7 +589,7 @@ class PageableList<T> extends ScrollableList<T> {
|
|||||||
ItemBuilder<T> itemBuilder,
|
ItemBuilder<T> itemBuilder,
|
||||||
bool itemsWrap: false,
|
bool itemsWrap: false,
|
||||||
double itemExtent,
|
double itemExtent,
|
||||||
PageChangedCallback this.pageChanged,
|
this.onPageChanged,
|
||||||
EdgeDims padding,
|
EdgeDims padding,
|
||||||
this.duration: const Duration(milliseconds: 200),
|
this.duration: const Duration(milliseconds: 200),
|
||||||
this.curve: ease
|
this.curve: ease
|
||||||
@ -607,7 +607,7 @@ class PageableList<T> extends ScrollableList<T> {
|
|||||||
|
|
||||||
final Duration duration;
|
final Duration duration;
|
||||||
final Curve curve;
|
final Curve curve;
|
||||||
final PageChangedCallback pageChanged;
|
final PageChangedCallback onPageChanged;
|
||||||
|
|
||||||
PageableListState<T> createState() => new PageableListState();
|
PageableListState<T> createState() => new PageableListState();
|
||||||
}
|
}
|
||||||
@ -633,8 +633,8 @@ class PageableListState<T> extends ScrollableListState<T, PageableList<T>> {
|
|||||||
int get currentPage => (scrollOffset / config.itemExtent).floor() % itemCount;
|
int get currentPage => (scrollOffset / config.itemExtent).floor() % itemCount;
|
||||||
|
|
||||||
void _notifyPageChanged(_) {
|
void _notifyPageChanged(_) {
|
||||||
if (config.pageChanged != null)
|
if (config.onPageChanged != null)
|
||||||
config.pageChanged(currentPage);
|
config.onPageChanged(currentPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void settleScrollOffset() {
|
void settleScrollOffset() {
|
||||||
|
@ -377,11 +377,17 @@ class RenderBlockViewport extends RenderBlockBase {
|
|||||||
|
|
||||||
void applyPaintTransform(Matrix4 transform) {
|
void applyPaintTransform(Matrix4 transform) {
|
||||||
super.applyPaintTransform(transform);
|
super.applyPaintTransform(transform);
|
||||||
|
if (isVertical)
|
||||||
transform.translate(0.0, startOffset);
|
transform.translate(0.0, startOffset);
|
||||||
|
else
|
||||||
|
transform.translate(startOffset, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hitTestChildren(HitTestResult result, { Point position }) {
|
void hitTestChildren(HitTestResult result, { Point position }) {
|
||||||
|
if (isVertical)
|
||||||
defaultHitTestChildren(result, position: position + new Offset(0.0, -startOffset));
|
defaultHitTestChildren(result, position: position + new Offset(0.0, -startOffset));
|
||||||
|
else
|
||||||
|
defaultHitTestChildren(result, position: position + new Offset(-startOffset, 0.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}startOffset: ${startOffset}\n';
|
String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}startOffset: ${startOffset}\n';
|
||||||
|
@ -25,15 +25,21 @@ class RootComponentState extends State<RootComponent> {
|
|||||||
|
|
||||||
class WidgetTester {
|
class WidgetTester {
|
||||||
|
|
||||||
|
// See thttps://github.com/flutter/engine/issues/1084 regarding frameTimeMs vs FakeAsync
|
||||||
|
|
||||||
void pumpFrame(Widget widget, [ double frameTimeMs = 0.0 ]) {
|
void pumpFrame(Widget widget, [ double frameTimeMs = 0.0 ]) {
|
||||||
runApp(widget);
|
runApp(widget);
|
||||||
scheduler.beginFrame(frameTimeMs); // TODO(ianh): https://github.com/flutter/engine/issues/1084
|
scheduler.beginFrame(frameTimeMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pumpFrameWithoutChange([ double frameTimeMs = 0.0 ]) {
|
void pumpFrameWithoutChange([ double frameTimeMs = 0.0 ]) {
|
||||||
scheduler.beginFrame(frameTimeMs); // TODO(ianh): https://github.com/flutter/engine/issues/1084
|
scheduler.beginFrame(frameTimeMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
runApp(new Container());
|
||||||
|
scheduler.beginFrame(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
List<Layer> _layers(Layer layer) {
|
List<Layer> _layers(Layer layer) {
|
||||||
List<Layer> result = [layer];
|
List<Layer> result = [layer];
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import 'package:quiver/testing/async.dart';
|
import 'package:quiver/testing/async.dart';
|
||||||
import 'package:sky/widgets.dart';
|
import 'package:sky/src/fn3.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import 'widget_tester.dart';
|
import '../fn3/widget_tester.dart';
|
||||||
|
|
||||||
const Size pageSize = const Size(800.0, 600.0);
|
const Size pageSize = const Size(800.0, 600.0);
|
||||||
const List<int> pages = const <int>[0, 1, 2, 3, 4, 5];
|
const List<int> pages = const <int>[0, 1, 2, 3, 4, 5];
|
||||||
int currentPage = null;
|
int currentPage = null;
|
||||||
bool itemsWrap = false;
|
bool itemsWrap = false;
|
||||||
|
|
||||||
Widget buildPage(int page) {
|
Widget buildPage(BuildContext context, int page) {
|
||||||
return new Container(
|
return new Container(
|
||||||
key: new ValueKey<int>(page),
|
key: new ValueKey<int>(page),
|
||||||
width: pageSize.width,
|
width: pageSize.width,
|
||||||
@ -20,14 +20,14 @@ Widget buildPage(int page) {
|
|||||||
|
|
||||||
Widget buildFrame() {
|
Widget buildFrame() {
|
||||||
// The test framework forces the frame (and so the PageableList)
|
// The test framework forces the frame (and so the PageableList)
|
||||||
// to be 800x600. The pageSize constant reflects as much.
|
// to be 800x600. The pageSize constant reflects this.
|
||||||
return new PageableList<int>(
|
return new PageableList<int>(
|
||||||
items: pages,
|
items: pages,
|
||||||
itemBuilder: buildPage,
|
itemBuilder: buildPage,
|
||||||
itemsWrap: itemsWrap,
|
itemsWrap: itemsWrap,
|
||||||
itemExtent: pageSize.width,
|
itemExtent: pageSize.width,
|
||||||
scrollDirection: ScrollDirection.horizontal,
|
scrollDirection: ScrollDirection.horizontal,
|
||||||
pageChanged: (int page) { currentPage = page; }
|
onPageChanged: (int page) { currentPage = page; }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,8 +36,8 @@ void page(WidgetTester tester, Offset offset) {
|
|||||||
new FakeAsync().run((async) {
|
new FakeAsync().run((async) {
|
||||||
tester.scroll(tester.findText(itemText), offset);
|
tester.scroll(tester.findText(itemText), offset);
|
||||||
// One frame to start the animation, a second to complete it.
|
// One frame to start the animation, a second to complete it.
|
||||||
tester.pumpFrame(buildFrame);
|
tester.pumpFrameWithoutChange();
|
||||||
tester.pumpFrame(buildFrame, 1000.0);
|
tester.pumpFrameWithoutChange(1000.0);
|
||||||
async.elapse(new Duration(seconds: 1));
|
async.elapse(new Duration(seconds: 1));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -57,42 +57,55 @@ void main() {
|
|||||||
WidgetTester tester = new WidgetTester();
|
WidgetTester tester = new WidgetTester();
|
||||||
currentPage = null;
|
currentPage = null;
|
||||||
itemsWrap = false;
|
itemsWrap = false;
|
||||||
tester.pumpFrame(buildFrame);
|
tester.pumpFrame(buildFrame());
|
||||||
expect(currentPage, isNull);
|
expect(currentPage, isNull);
|
||||||
pageLeft(tester);
|
pageLeft(tester);
|
||||||
expect(currentPage, equals(1));
|
expect(currentPage, equals(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Underscroll (scroll right), return to page 0', () {
|
test('Scroll right from page 1 to page 0', () {
|
||||||
WidgetTester tester = new WidgetTester();
|
WidgetTester tester = new WidgetTester();
|
||||||
currentPage = null;
|
|
||||||
itemsWrap = false;
|
itemsWrap = false;
|
||||||
tester.pumpFrame(buildFrame);
|
tester.pumpFrame(buildFrame());
|
||||||
expect(currentPage, isNull);
|
expect(currentPage, equals(1));
|
||||||
|
pageRight(tester);
|
||||||
|
expect(currentPage, equals(0));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Scroll right from page 0 does nothing (underscroll)', () {
|
||||||
|
WidgetTester tester = new WidgetTester();
|
||||||
|
itemsWrap = false;
|
||||||
|
tester.pumpFrame(buildFrame());
|
||||||
|
expect(currentPage, equals(0));
|
||||||
pageRight(tester);
|
pageRight(tester);
|
||||||
expect(currentPage, equals(0));
|
expect(currentPage, equals(0));
|
||||||
});
|
});
|
||||||
|
|
||||||
// PageableList with itemsWrap: true
|
// PageableList with itemsWrap: true
|
||||||
|
|
||||||
itemsWrap = true;
|
|
||||||
|
|
||||||
test('Scroll left page 0 to page 1, itemsWrap: true', () {
|
test('Scroll left page 0 to page 1, itemsWrap: true', () {
|
||||||
WidgetTester tester = new WidgetTester();
|
WidgetTester tester = new WidgetTester();
|
||||||
|
tester.reset();
|
||||||
currentPage = null;
|
currentPage = null;
|
||||||
itemsWrap = true;
|
itemsWrap = true;
|
||||||
tester.pumpFrame(buildFrame);
|
tester.pumpFrame(buildFrame());
|
||||||
expect(currentPage, isNull);
|
expect(currentPage, isNull);
|
||||||
pageLeft(tester);
|
pageLeft(tester);
|
||||||
expect(currentPage, equals(1));
|
expect(currentPage, equals(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Scroll right from page 0 to page 5, itemsWrap: true', () {
|
test('Scroll right from page 1 to page 0, itemsWrap: true', () {
|
||||||
WidgetTester tester = new WidgetTester();
|
WidgetTester tester = new WidgetTester();
|
||||||
currentPage = null;
|
tester.pumpFrame(buildFrame());
|
||||||
itemsWrap = true;
|
expect(currentPage, equals(1));
|
||||||
tester.pumpFrame(buildFrame);
|
pageRight(tester);
|
||||||
expect(currentPage, isNull);
|
expect(currentPage, equals(0));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Scroll right from page 0 to page 5, itemsWrap: true (underscroll)', () {
|
||||||
|
WidgetTester tester = new WidgetTester();
|
||||||
|
tester.pumpFrame(buildFrame());
|
||||||
|
expect(currentPage, equals(0));
|
||||||
pageRight(tester);
|
pageRight(tester);
|
||||||
expect(currentPage, equals(5));
|
expect(currentPage, equals(5));
|
||||||
});
|
});
|
||||||
|
@ -0,0 +1,99 @@
|
|||||||
|
import 'package:quiver/testing/async.dart';
|
||||||
|
import 'package:sky/rendering.dart';
|
||||||
|
import 'package:sky/src/fn3.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
import '../fn3/widget_tester.dart';
|
||||||
|
|
||||||
|
const List<int> items = const <int>[0, 1, 2, 3, 4, 5];
|
||||||
|
List<int> tapped = <int>[];
|
||||||
|
|
||||||
|
Widget buildFrame() {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
double t = 0.0;
|
||||||
|
WidgetTester tester = new WidgetTester();
|
||||||
|
|
||||||
|
test('Tap item after scroll - horizontal', () {
|
||||||
|
tester.pumpFrame(new Center(
|
||||||
|
child: new Container(
|
||||||
|
height: 50.0,
|
||||||
|
child: new ScrollableList<int>(
|
||||||
|
key: new GlobalKey(),
|
||||||
|
items: items,
|
||||||
|
itemBuilder: (BuildContext context, int item) {
|
||||||
|
return new Container(
|
||||||
|
key: new ValueKey<int>(item),
|
||||||
|
child: new GestureDetector(
|
||||||
|
onTap: () { tapped.add(item); },
|
||||||
|
child: new Text('$item')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemExtent: 290.0,
|
||||||
|
scrollDirection: ScrollDirection.horizontal
|
||||||
|
)
|
||||||
|
)
|
||||||
|
), t);
|
||||||
|
tester.scroll(tester.findText('2'), const Offset(-280.0, 0.0));
|
||||||
|
tester.pumpFrameWithoutChange(t += 1000.0);
|
||||||
|
// screen is 800px wide, and has the following items:
|
||||||
|
// -280..10 = 0
|
||||||
|
// 10..300 = 1
|
||||||
|
// 300..590 = 2
|
||||||
|
// 590..880 = 3
|
||||||
|
expect(tester.findText('0'), isNotNull);
|
||||||
|
expect(tester.findText('1'), isNotNull);
|
||||||
|
expect(tester.findText('2'), isNotNull);
|
||||||
|
expect(tester.findText('3'), isNotNull);
|
||||||
|
expect(tester.findText('4'), isNull);
|
||||||
|
expect(tester.findText('5'), isNull);
|
||||||
|
expect(tapped, equals([]));
|
||||||
|
tester.tap(tester.findText('2'));
|
||||||
|
expect(tapped, equals([2]));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Tap item after scroll - vertical', () {
|
||||||
|
tester.pumpFrame(new Center(
|
||||||
|
child: new Container(
|
||||||
|
width: 50.0,
|
||||||
|
child: new ScrollableList<int>(
|
||||||
|
key: new GlobalKey(),
|
||||||
|
items: items,
|
||||||
|
itemBuilder: (BuildContext context, int item) {
|
||||||
|
return new Container(
|
||||||
|
key: new ValueKey<int>(item),
|
||||||
|
child: new GestureDetector(
|
||||||
|
onTap: () { tapped.add(item); },
|
||||||
|
child: new Text('$item')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemExtent: 290.0,
|
||||||
|
scrollDirection: ScrollDirection.vertical
|
||||||
|
)
|
||||||
|
)
|
||||||
|
), t);
|
||||||
|
tester.scroll(tester.findText('1'), const Offset(0.0, -280.0));
|
||||||
|
tester.pumpFrameWithoutChange(t += 1000.0);
|
||||||
|
// screen is 600px tall, and has the following items:
|
||||||
|
// -280..10 = 0
|
||||||
|
// 10..300 = 1
|
||||||
|
// 300..590 = 2
|
||||||
|
// 590..880 = 3
|
||||||
|
expect(tester.findText('0'), isNotNull);
|
||||||
|
expect(tester.findText('1'), isNotNull);
|
||||||
|
expect(tester.findText('2'), isNotNull);
|
||||||
|
expect(tester.findText('3'), isNotNull);
|
||||||
|
expect(tester.findText('4'), isNull);
|
||||||
|
expect(tester.findText('5'), isNull);
|
||||||
|
expect(tapped, equals([2]));
|
||||||
|
tester.tap(tester.findText('1'));
|
||||||
|
expect(tapped, equals([2, 1]));
|
||||||
|
tester.tap(tester.findText('3'));
|
||||||
|
expect(tapped, equals([2, 1])); // the center of the third item is off-screen so it shouldn't get hit
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
161
packages/unit/test/widget/scrollable_list_horizontal_test.dart
Normal file
161
packages/unit/test/widget/scrollable_list_horizontal_test.dart
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
import 'package:quiver/testing/async.dart';
|
||||||
|
import 'package:sky/rendering.dart';
|
||||||
|
import 'package:sky/src/fn3.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
import '../fn3/widget_tester.dart';
|
||||||
|
|
||||||
|
const List<int> items = const <int>[0, 1, 2, 3, 4, 5];
|
||||||
|
|
||||||
|
Widget buildFrame() {
|
||||||
|
return new Center(
|
||||||
|
child: new Container(
|
||||||
|
height: 50.0,
|
||||||
|
child: new ScrollableList<int>(
|
||||||
|
items: items,
|
||||||
|
itemBuilder: (BuildContext context, int item) {
|
||||||
|
return new Container(
|
||||||
|
key: new ValueKey<int>(item),
|
||||||
|
child: new Text('$item')
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemExtent: 290.0,
|
||||||
|
scrollDirection: ScrollDirection.horizontal
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
double t = 0.0;
|
||||||
|
WidgetTester tester = new WidgetTester();
|
||||||
|
tester.pumpFrame(buildFrame());
|
||||||
|
|
||||||
|
test('Drag to the left using item 1', () {
|
||||||
|
tester.pumpFrameWithoutChange(t += 1000.0);
|
||||||
|
tester.scroll(tester.findText('1'), const Offset(-300.0, 0.0));
|
||||||
|
tester.pumpFrameWithoutChange(t += 1000.0);
|
||||||
|
// screen is 800px wide, and has the following items:
|
||||||
|
// -10..280 = 1
|
||||||
|
// 280..570 = 2
|
||||||
|
// 570..860 = 3
|
||||||
|
expect(tester.findText('0'), isNull);
|
||||||
|
expect(tester.findText('1'), isNotNull);
|
||||||
|
expect(tester.findText('2'), isNotNull);
|
||||||
|
expect(tester.findText('3'), isNotNull);
|
||||||
|
expect(tester.findText('4'), isNull);
|
||||||
|
expect(tester.findText('5'), isNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Drag to the left using item 3', () {
|
||||||
|
// the center of item 3 is visible, so this works;
|
||||||
|
// if item 3 was a bit wider, such that it's center was past the 800px mark, this would fail,
|
||||||
|
// because it wouldn't be hit tested when scrolling from its center, as scroll() does.
|
||||||
|
tester.pumpFrameWithoutChange(t += 1000.0);
|
||||||
|
tester.scroll(tester.findText('3'), const Offset(-290.0, 0.0));
|
||||||
|
tester.pumpFrameWithoutChange(t += 1000.0);
|
||||||
|
// screen is 800px wide, and has the following items:
|
||||||
|
// -10..280 = 2
|
||||||
|
// 280..570 = 3
|
||||||
|
// 570..860 = 4
|
||||||
|
expect(tester.findText('0'), isNull);
|
||||||
|
expect(tester.findText('1'), isNull);
|
||||||
|
expect(tester.findText('2'), isNotNull);
|
||||||
|
expect(tester.findText('3'), isNotNull);
|
||||||
|
expect(tester.findText('4'), isNotNull);
|
||||||
|
expect(tester.findText('5'), isNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Drag up using item 3', () {
|
||||||
|
tester.pumpFrameWithoutChange(t += 1000.0);
|
||||||
|
tester.scroll(tester.findText('3'), const Offset(0.0, -290.0));
|
||||||
|
tester.pumpFrameWithoutChange(t += 1000.0);
|
||||||
|
// unchanged
|
||||||
|
expect(tester.findText('0'), isNull);
|
||||||
|
expect(tester.findText('1'), isNull);
|
||||||
|
expect(tester.findText('2'), isNotNull);
|
||||||
|
expect(tester.findText('3'), isNotNull);
|
||||||
|
expect(tester.findText('4'), isNotNull);
|
||||||
|
expect(tester.findText('5'), isNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Drag to the left using item 3 again', () {
|
||||||
|
tester.pumpFrameWithoutChange(t += 1000.0);
|
||||||
|
tester.scroll(tester.findText('3'), const Offset(-290.0, 0.0));
|
||||||
|
tester.pumpFrameWithoutChange(t += 1000.0);
|
||||||
|
// screen is 800px wide, and has the following items:
|
||||||
|
// -10..280 = 3
|
||||||
|
// 280..570 = 4
|
||||||
|
// 570..860 = 5
|
||||||
|
expect(tester.findText('0'), isNull);
|
||||||
|
expect(tester.findText('1'), isNull);
|
||||||
|
expect(tester.findText('2'), isNull);
|
||||||
|
expect(tester.findText('3'), isNotNull);
|
||||||
|
expect(tester.findText('4'), isNotNull);
|
||||||
|
expect(tester.findText('5'), isNotNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Drag to the left using item 3 again again (past the end of the list)', () {
|
||||||
|
tester.pumpFrameWithoutChange(t += 1000.0);
|
||||||
|
// at this point we can drag 60 pixels further before we hit the friction zone
|
||||||
|
// then, every pixel we drag is equivalent to half a pixel of movement
|
||||||
|
// to move item 3 entirely off screen therefore takes:
|
||||||
|
// 60 + (290-60)*2 = 520 pixels
|
||||||
|
// plus a couple more to be sure
|
||||||
|
tester.scroll(tester.findText('3'), const Offset(-522.0, 0.0));
|
||||||
|
tester.pumpFrameWithoutChange(t += 0.0); // just after release
|
||||||
|
// screen is 800px wide, and has the following items:
|
||||||
|
// -11..279 = 4
|
||||||
|
// 279..569 = 5
|
||||||
|
expect(tester.findText('0'), isNull);
|
||||||
|
expect(tester.findText('1'), isNull);
|
||||||
|
expect(tester.findText('2'), isNull);
|
||||||
|
expect(tester.findText('3'), isNull);
|
||||||
|
expect(tester.findText('4'), isNotNull);
|
||||||
|
expect(tester.findText('5'), isNotNull);
|
||||||
|
tester.pumpFrameWithoutChange(t += 1000.0); // a second after release
|
||||||
|
// screen is 800px wide, and has the following items:
|
||||||
|
// -70..220 = 3
|
||||||
|
// 220..510 = 4
|
||||||
|
// 510..800 = 5
|
||||||
|
expect(tester.findText('0'), isNull);
|
||||||
|
expect(tester.findText('1'), isNull);
|
||||||
|
expect(tester.findText('2'), isNull);
|
||||||
|
expect(tester.findText('3'), isNotNull);
|
||||||
|
expect(tester.findText('4'), isNotNull);
|
||||||
|
expect(tester.findText('5'), isNotNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Drag to the left using item 2 when the scroll offset is big', () {
|
||||||
|
tester.reset();
|
||||||
|
tester.pumpFrame(buildFrame(), t += 1000.0);
|
||||||
|
tester.scroll(tester.findText('2'), const Offset(-280.0, 0.0));
|
||||||
|
tester.pumpFrameWithoutChange(t += 1000.0);
|
||||||
|
// screen is 800px wide, and has the following items:
|
||||||
|
// -280..10 = 0
|
||||||
|
// 10..300 = 1
|
||||||
|
// 300..590 = 2
|
||||||
|
// 590..880 = 3
|
||||||
|
expect(tester.findText('0'), isNotNull);
|
||||||
|
expect(tester.findText('1'), isNotNull);
|
||||||
|
expect(tester.findText('2'), isNotNull);
|
||||||
|
expect(tester.findText('3'), isNotNull);
|
||||||
|
expect(tester.findText('4'), isNull);
|
||||||
|
expect(tester.findText('5'), isNull);
|
||||||
|
tester.pumpFrameWithoutChange(t += 1000.0);
|
||||||
|
tester.scroll(tester.findText('2'), const Offset(-290.0, 0.0));
|
||||||
|
tester.pumpFrameWithoutChange(t += 1000.0);
|
||||||
|
// screen is 800px wide, and has the following items:
|
||||||
|
// -280..10 = 1
|
||||||
|
// 10..300 = 2
|
||||||
|
// 300..590 = 3
|
||||||
|
// 590..880 = 4
|
||||||
|
expect(tester.findText('0'), isNull);
|
||||||
|
expect(tester.findText('1'), isNotNull);
|
||||||
|
expect(tester.findText('2'), isNotNull);
|
||||||
|
expect(tester.findText('3'), isNotNull);
|
||||||
|
expect(tester.findText('4'), isNotNull);
|
||||||
|
expect(tester.findText('5'), isNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
72
packages/unit/test/widget/scrollable_list_vertical_test.dart
Normal file
72
packages/unit/test/widget/scrollable_list_vertical_test.dart
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import 'package:quiver/testing/async.dart';
|
||||||
|
import 'package:sky/src/fn3.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
import '../fn3/widget_tester.dart';
|
||||||
|
|
||||||
|
const List<int> items = const <int>[0, 1, 2, 3, 4, 5];
|
||||||
|
|
||||||
|
Widget buildFrame() {
|
||||||
|
return new ScrollableList<int>(
|
||||||
|
items: items,
|
||||||
|
itemBuilder: (BuildContext context, int item) {
|
||||||
|
return new Container(
|
||||||
|
key: new ValueKey<int>(item),
|
||||||
|
child: new Text('$item')
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemExtent: 290.0,
|
||||||
|
scrollDirection: ScrollDirection.vertical
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
WidgetTester tester = new WidgetTester();
|
||||||
|
tester.pumpFrame(buildFrame());
|
||||||
|
|
||||||
|
test('Drag up using item 1', () {
|
||||||
|
tester.pumpFrameWithoutChange();
|
||||||
|
tester.scroll(tester.findText('1'), const Offset(0.0, -300.0));
|
||||||
|
tester.pumpFrameWithoutChange();
|
||||||
|
// screen is 600px high, and has the following items:
|
||||||
|
// -10..280 = 1
|
||||||
|
// 280..570 = 2
|
||||||
|
// 570..860 = 3
|
||||||
|
expect(tester.findText('0'), isNull);
|
||||||
|
expect(tester.findText('1'), isNotNull);
|
||||||
|
expect(tester.findText('2'), isNotNull);
|
||||||
|
expect(tester.findText('3'), isNotNull);
|
||||||
|
expect(tester.findText('4'), isNull);
|
||||||
|
expect(tester.findText('5'), isNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Drag up using item 2', () {
|
||||||
|
tester.pumpFrameWithoutChange();
|
||||||
|
tester.scroll(tester.findText('2'), const Offset(0.0, -290.0));
|
||||||
|
tester.pumpFrameWithoutChange();
|
||||||
|
// screen is 600px high, and has the following items:
|
||||||
|
// -10..280 = 2
|
||||||
|
// 280..570 = 3
|
||||||
|
// 570..860 = 4
|
||||||
|
expect(tester.findText('0'), isNull);
|
||||||
|
expect(tester.findText('1'), isNull);
|
||||||
|
expect(tester.findText('2'), isNotNull);
|
||||||
|
expect(tester.findText('3'), isNotNull);
|
||||||
|
expect(tester.findText('4'), isNotNull);
|
||||||
|
expect(tester.findText('5'), isNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Drag to the left using item 3', () {
|
||||||
|
tester.pumpFrameWithoutChange();
|
||||||
|
tester.scroll(tester.findText('3'), const Offset(-300.0, 0.0));
|
||||||
|
tester.pumpFrameWithoutChange();
|
||||||
|
// nothing should have changed
|
||||||
|
expect(tester.findText('0'), isNull);
|
||||||
|
expect(tester.findText('1'), isNull);
|
||||||
|
expect(tester.findText('2'), isNotNull);
|
||||||
|
expect(tester.findText('3'), isNotNull);
|
||||||
|
expect(tester.findText('4'), isNotNull);
|
||||||
|
expect(tester.findText('5'), isNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user