mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Restore PageableList itemsWrap:true
Makes PageableList with itemsWrap:true work again. Plumbed the itemsWrap parameter through to HomogenousViewport. Fixes issue #877.
This commit is contained in:
parent
02ebc4fa67
commit
a69a95df26
@ -16,6 +16,7 @@ class HomogeneousViewport extends RenderObjectWrapper {
|
|||||||
HomogeneousViewport({
|
HomogeneousViewport({
|
||||||
Key key,
|
Key key,
|
||||||
this.builder,
|
this.builder,
|
||||||
|
this.itemsWrap: false,
|
||||||
this.itemExtent, // required
|
this.itemExtent, // required
|
||||||
this.itemCount, // optional, but you cannot shrink-wrap this class or otherwise use its intrinsic dimensions if you don't specify it
|
this.itemCount, // optional, but you cannot shrink-wrap this class or otherwise use its intrinsic dimensions if you don't specify it
|
||||||
this.direction: ScrollDirection.vertical,
|
this.direction: ScrollDirection.vertical,
|
||||||
@ -25,6 +26,7 @@ class HomogeneousViewport extends RenderObjectWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ListBuilder builder;
|
ListBuilder builder;
|
||||||
|
bool itemsWrap;
|
||||||
double itemExtent;
|
double itemExtent;
|
||||||
int itemCount;
|
int itemCount;
|
||||||
ScrollDirection direction;
|
ScrollDirection direction;
|
||||||
@ -115,16 +117,16 @@ class HomogeneousViewport extends RenderObjectWrapper {
|
|||||||
try {
|
try {
|
||||||
double mainAxisExtent = direction == ScrollDirection.vertical ? constraints.maxHeight : constraints.maxWidth;
|
double mainAxisExtent = direction == ScrollDirection.vertical ? constraints.maxHeight : constraints.maxWidth;
|
||||||
double offset;
|
double offset;
|
||||||
if (startOffset <= 0.0) {
|
if (startOffset <= 0.0 && !itemsWrap) {
|
||||||
_layoutFirstIndex = 0;
|
_layoutFirstIndex = 0;
|
||||||
offset = -startOffset;
|
offset = -startOffset;
|
||||||
} else {
|
} else {
|
||||||
_layoutFirstIndex = startOffset ~/ itemExtent;
|
_layoutFirstIndex = (startOffset / itemExtent).floor();
|
||||||
offset = -(startOffset % itemExtent);
|
offset = -(startOffset % itemExtent);
|
||||||
}
|
}
|
||||||
if (mainAxisExtent < double.INFINITY) {
|
if (mainAxisExtent < double.INFINITY) {
|
||||||
_layoutItemCount = ((mainAxisExtent - offset) / itemExtent).ceil();
|
_layoutItemCount = ((mainAxisExtent - offset) / itemExtent).ceil();
|
||||||
if (itemCount != null)
|
if (itemCount != null && !itemsWrap)
|
||||||
_layoutItemCount = math.min(_layoutItemCount, itemCount - _layoutFirstIndex);
|
_layoutItemCount = math.min(_layoutItemCount, itemCount - _layoutFirstIndex);
|
||||||
} else {
|
} else {
|
||||||
assert(() {
|
assert(() {
|
||||||
|
@ -348,6 +348,7 @@ abstract class ScrollableWidgetList extends Scrollable {
|
|||||||
Key key,
|
Key key,
|
||||||
double initialScrollOffset,
|
double initialScrollOffset,
|
||||||
ScrollDirection scrollDirection: ScrollDirection.vertical,
|
ScrollDirection scrollDirection: ScrollDirection.vertical,
|
||||||
|
this.itemsWrap: false,
|
||||||
this.itemExtent,
|
this.itemExtent,
|
||||||
this.padding
|
this.padding
|
||||||
}) : super(key: key, initialScrollOffset: initialScrollOffset, scrollDirection: scrollDirection) {
|
}) : super(key: key, initialScrollOffset: initialScrollOffset, scrollDirection: scrollDirection) {
|
||||||
@ -355,6 +356,7 @@ abstract class ScrollableWidgetList extends Scrollable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EdgeDims padding;
|
EdgeDims padding;
|
||||||
|
bool itemsWrap;
|
||||||
double itemExtent;
|
double itemExtent;
|
||||||
Size containerSize = Size.zero;
|
Size containerSize = Size.zero;
|
||||||
|
|
||||||
@ -441,6 +443,7 @@ abstract class ScrollableWidgetList extends Scrollable {
|
|||||||
padding: _crossAxisPadding,
|
padding: _crossAxisPadding,
|
||||||
child: new HomogeneousViewport(
|
child: new HomogeneousViewport(
|
||||||
builder: _buildItems,
|
builder: _buildItems,
|
||||||
|
itemsWrap: itemsWrap,
|
||||||
itemExtent: itemExtent,
|
itemExtent: itemExtent,
|
||||||
itemCount: itemCount,
|
itemCount: itemCount,
|
||||||
direction: scrollDirection,
|
direction: scrollDirection,
|
||||||
@ -472,19 +475,19 @@ class ScrollableList<T> extends ScrollableWidgetList {
|
|||||||
ScrollDirection scrollDirection: ScrollDirection.vertical,
|
ScrollDirection scrollDirection: ScrollDirection.vertical,
|
||||||
this.items,
|
this.items,
|
||||||
this.itemBuilder,
|
this.itemBuilder,
|
||||||
this.itemsWrap: false,
|
itemsWrap: false,
|
||||||
double itemExtent,
|
double itemExtent,
|
||||||
EdgeDims padding
|
EdgeDims padding
|
||||||
}) : super(
|
}) : super(
|
||||||
key: key,
|
key: key,
|
||||||
initialScrollOffset: initialScrollOffset,
|
initialScrollOffset: initialScrollOffset,
|
||||||
scrollDirection: scrollDirection,
|
scrollDirection: scrollDirection,
|
||||||
|
itemsWrap: itemsWrap,
|
||||||
itemExtent: itemExtent,
|
itemExtent: itemExtent,
|
||||||
padding: padding);
|
padding: padding);
|
||||||
|
|
||||||
List<T> items;
|
List<T> items;
|
||||||
ItemBuilder<T> itemBuilder;
|
ItemBuilder<T> itemBuilder;
|
||||||
bool itemsWrap;
|
|
||||||
|
|
||||||
void syncConstructorArguments(ScrollableList<T> source) {
|
void syncConstructorArguments(ScrollableList<T> source) {
|
||||||
items = source.items;
|
items = source.items;
|
||||||
@ -568,7 +571,7 @@ class PageableList<T> extends ScrollableList<T> {
|
|||||||
return EventDisposition.processed;
|
return EventDisposition.processed;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get currentPage => (scrollOffset / itemExtent).floor();
|
int get currentPage => (scrollOffset / itemExtent).floor() % itemCount;
|
||||||
|
|
||||||
void _notifyPageChanged(_) {
|
void _notifyPageChanged(_) {
|
||||||
if (pageChanged != null)
|
if (pageChanged != null)
|
||||||
|
@ -4,13 +4,9 @@ import 'package:test/test.dart';
|
|||||||
|
|
||||||
import 'widget_tester.dart';
|
import 'widget_tester.dart';
|
||||||
|
|
||||||
void main() {
|
const Size pageSize = const Size(800.0, 600.0);
|
||||||
test('Scrolling changes page', () {
|
const List<int> pages = const <int>[0, 1, 2, 3, 4, 5];
|
||||||
WidgetTester tester = new WidgetTester();
|
int currentPage = null;
|
||||||
|
|
||||||
List<int> pages = [0, 1, 2, 3, 4, 5];
|
|
||||||
Size pageSize = new Size(200.0, 200.0);
|
|
||||||
int currentPage;
|
|
||||||
|
|
||||||
Widget buildPage(int page) {
|
Widget buildPage(int page) {
|
||||||
return new Container(
|
return new Container(
|
||||||
@ -21,32 +17,76 @@ void main() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget builder() {
|
Widget buildFrame({ bool itemsWrap: false }) {
|
||||||
return new Container(
|
// The test framework forces the frame (and so the PageableList)
|
||||||
height: pageSize.height,
|
// to be 800x600. The pageSize constant reflects as much.
|
||||||
child: new PageableList<int>(
|
return new PageableList<int>(
|
||||||
padding: new EdgeDims.symmetric(horizontal: 10.0),
|
|
||||||
items: pages,
|
items: pages,
|
||||||
itemBuilder: buildPage,
|
itemBuilder: buildPage,
|
||||||
scrollDirection: ScrollDirection.horizontal,
|
itemsWrap: itemsWrap,
|
||||||
itemExtent: pageSize.width,
|
itemExtent: pageSize.width,
|
||||||
pageChanged: (int page) {
|
scrollDirection: ScrollDirection.horizontal,
|
||||||
currentPage = page;
|
pageChanged: (int page) { currentPage = page; }
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
tester.pumpFrame(builder);
|
void page(WidgetTester tester, Offset offset) {
|
||||||
|
String itemText = currentPage != null ? currentPage.toString() : '0';
|
||||||
expect(currentPage, isNull);
|
|
||||||
new FakeAsync().run((async) {
|
new FakeAsync().run((async) {
|
||||||
tester.scroll(tester.findText('1'), new Offset(-300.0, 0.0));
|
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(builder);
|
tester.pumpFrame(buildFrame);
|
||||||
tester.pumpFrame(builder, 5000.0);
|
tester.pumpFrame(buildFrame, 1000.0);
|
||||||
async.elapse(new Duration(seconds: 5));
|
async.elapse(new Duration(seconds: 1));
|
||||||
expect(currentPage, equals(2));
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
void pageLeft(WidgetTester tester) {
|
||||||
|
page(tester, new Offset(-pageSize.width, 0.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void pageRight(WidgetTester tester) {
|
||||||
|
page(tester, new Offset(pageSize.width, 0.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// PageableList with itemsWrap: false
|
||||||
|
|
||||||
|
test('Scroll left from page 0 to page 1', () {
|
||||||
|
WidgetTester tester = new WidgetTester();
|
||||||
|
currentPage = null;
|
||||||
|
tester.pumpFrame(buildFrame);
|
||||||
|
expect(currentPage, isNull);
|
||||||
|
pageLeft(tester);
|
||||||
|
expect(currentPage, equals(1));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Underscroll (scroll right), return to page 0', () {
|
||||||
|
WidgetTester tester = new WidgetTester();
|
||||||
|
currentPage = null;
|
||||||
|
tester.pumpFrame(buildFrame);
|
||||||
|
expect(currentPage, isNull);
|
||||||
|
pageRight(tester);
|
||||||
|
expect(currentPage, equals(0));
|
||||||
|
});
|
||||||
|
|
||||||
|
// PageableList with itemsWrap: true
|
||||||
|
|
||||||
|
test('Scroll left page 0 to page 1, itemsWrap: true', () {
|
||||||
|
WidgetTester tester = new WidgetTester();
|
||||||
|
currentPage = null;
|
||||||
|
tester.pumpFrame(() { return buildFrame(itemsWrap: true); });
|
||||||
|
expect(currentPage, isNull);
|
||||||
|
pageLeft(tester);
|
||||||
|
expect(currentPage, equals(1));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Scroll right from page 0 to page 5, itemsWrap: true', () {
|
||||||
|
WidgetTester tester = new WidgetTester();
|
||||||
|
currentPage = null;
|
||||||
|
tester.pumpFrame(() { return buildFrame(itemsWrap: true); });
|
||||||
|
expect(currentPage, isNull);
|
||||||
|
pageRight(tester);
|
||||||
|
expect(currentPage, equals(5));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -117,8 +117,10 @@ class WidgetTester {
|
|||||||
void scroll(Widget widget, Offset offset, { int pointer: 1 }) {
|
void scroll(Widget widget, Offset offset, { int pointer: 1 }) {
|
||||||
Point startLocation = getCenter(widget);
|
Point startLocation = getCenter(widget);
|
||||||
Point endLocation = startLocation + offset;
|
Point endLocation = startLocation + offset;
|
||||||
HitTestResult result = _hitTest(startLocation);
|
|
||||||
TestPointer p = new TestPointer(pointer);
|
TestPointer p = new TestPointer(pointer);
|
||||||
|
// Events for the entire press-drag-release gesture are dispatched
|
||||||
|
// to the widgets "hit" by the pointer down event.
|
||||||
|
HitTestResult result = _hitTest(startLocation);
|
||||||
_dispatchEvent(p.down(startLocation), result);
|
_dispatchEvent(p.down(startLocation), result);
|
||||||
_dispatchEvent(p.move(endLocation), result);
|
_dispatchEvent(p.move(endLocation), result);
|
||||||
_dispatchEvent(p.up(), result);
|
_dispatchEvent(p.up(), result);
|
||||||
|
Loading…
Reference in New Issue
Block a user