Commit 13baf51e authored by Hans Muller's avatar Hans Muller

Merge pull request #864 from HansMuller/zero_items

Support an empty PageableList

Corrected support for PagebleList when zero items or no items are specified.

Added some final qualifiers in pageable_list.dart
parents a9f0044e fcfcfd56
...@@ -256,7 +256,6 @@ class _HomogeneousPageViewportElement extends _ViewportBaseElement<HomogeneousPa ...@@ -256,7 +256,6 @@ class _HomogeneousPageViewportElement extends _ViewportBaseElement<HomogeneousPa
// doing our own layout.) // doing our own layout.)
BuildableElement.lockState(() { BuildableElement.lockState(() {
double itemExtent = widget.direction == ScrollDirection.vertical ? constraints.maxHeight : constraints.maxWidth; double itemExtent = widget.direction == ScrollDirection.vertical ? constraints.maxHeight : constraints.maxWidth;
double contentExtent = itemExtent * widget.itemCount;
double offset; double offset;
if (widget.startOffset <= 0.0 && !widget.itemsWrap) { if (widget.startOffset <= 0.0 && !widget.itemsWrap) {
_layoutFirstIndex = 0; _layoutFirstIndex = 0;
...@@ -265,9 +264,10 @@ class _HomogeneousPageViewportElement extends _ViewportBaseElement<HomogeneousPa ...@@ -265,9 +264,10 @@ class _HomogeneousPageViewportElement extends _ViewportBaseElement<HomogeneousPa
_layoutFirstIndex = widget.startOffset.floor(); _layoutFirstIndex = widget.startOffset.floor();
offset = -((widget.startOffset * itemExtent) % itemExtent); offset = -((widget.startOffset * itemExtent) % itemExtent);
} }
if (itemExtent < double.INFINITY) { if (itemExtent < double.INFINITY && widget.itemCount != null) {
_layoutItemCount = ((contentExtent - offset) / contentExtent).ceil(); final double contentExtent = itemExtent * widget.itemCount;
if (widget.itemCount != null && !widget.itemsWrap) _layoutItemCount = contentExtent == 0.0 ? 0 : ((contentExtent - offset) / contentExtent).ceil();
if (!widget.itemsWrap)
_layoutItemCount = math.min(_layoutItemCount, widget.itemCount - _layoutFirstIndex); _layoutItemCount = math.min(_layoutItemCount, widget.itemCount - _layoutFirstIndex);
} else { } else {
assert(() { assert(() {
......
...@@ -148,15 +148,15 @@ class PageableListState<T, Config extends PageableList<T>> extends ScrollableSta ...@@ -148,15 +148,15 @@ class PageableListState<T, Config extends PageableList<T>> extends ScrollableSta
bool get snapScrollOffsetChanges => config.itemsSnapAlignment == ItemsSnapAlignment.item; bool get snapScrollOffsetChanges => config.itemsSnapAlignment == ItemsSnapAlignment.item;
double snapScrollOffset(double newScrollOffset) { double snapScrollOffset(double newScrollOffset) {
double previousItemOffset = newScrollOffset.floorToDouble(); final double previousItemOffset = newScrollOffset.floorToDouble();
double nextItemOffset = newScrollOffset.ceilToDouble(); final double nextItemOffset = newScrollOffset.ceilToDouble();
return (newScrollOffset - previousItemOffset < 0.5 ? previousItemOffset : nextItemOffset) return (newScrollOffset - previousItemOffset < 0.5 ? previousItemOffset : nextItemOffset)
.clamp(scrollBehavior.minScrollOffset, scrollBehavior.maxScrollOffset); .clamp(scrollBehavior.minScrollOffset, scrollBehavior.maxScrollOffset);
} }
Future _flingToAdjacentItem(Offset velocity) { Future _flingToAdjacentItem(Offset velocity) {
double scrollVelocity = scrollDirectionVelocity(velocity); final double scrollVelocity = scrollDirectionVelocity(velocity);
double newScrollOffset = snapScrollOffset(scrollOffset + scrollVelocity.sign) final double newScrollOffset = snapScrollOffset(scrollOffset + scrollVelocity.sign)
.clamp(snapScrollOffset(scrollOffset - 0.5), snapScrollOffset(scrollOffset + 0.5)); .clamp(snapScrollOffset(scrollOffset - 0.5), snapScrollOffset(scrollOffset + 0.5));
return scrollTo(newScrollOffset, duration: config.duration, curve: config.curve) return scrollTo(newScrollOffset, duration: config.duration, curve: config.curve)
.then(_notifyPageChanged); .then(_notifyPageChanged);
...@@ -177,9 +177,9 @@ class PageableListState<T, Config extends PageableList<T>> extends ScrollableSta ...@@ -177,9 +177,9 @@ class PageableListState<T, Config extends PageableList<T>> extends ScrollableSta
} }
List<Widget> buildItems(BuildContext context, int start, int count) { List<Widget> buildItems(BuildContext context, int start, int count) {
List<Widget> result = new List<Widget>(); final List<Widget> result = new List<Widget>();
int begin = config.itemsWrap ? start : math.max(0, start); final int begin = config.itemsWrap ? start : math.max(0, start);
int end = config.itemsWrap ? begin + count : math.min(begin + count, config.items.length); final int end = config.itemsWrap ? begin + count : math.min(begin + count, itemCount);
for (int i = begin; i < end; ++i) for (int i = begin; i < end; ++i)
result.add(config.itemBuilder(context, config.items[i % itemCount], i)); result.add(config.itemBuilder(context, config.items[i % itemCount], i));
assert(result.every((Widget item) => item.key != null)); assert(result.every((Widget item) => item.key != null));
......
...@@ -7,7 +7,7 @@ import 'package:flutter/widgets.dart'; ...@@ -7,7 +7,7 @@ import 'package:flutter/widgets.dart';
import 'package:test/test.dart'; import 'package:test/test.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> defaultPages = const <int>[0, 1, 2, 3, 4, 5];
int currentPage = null; int currentPage = null;
bool itemsWrap = false; bool itemsWrap = false;
...@@ -20,7 +20,7 @@ Widget buildPage(BuildContext context, int page, int index) { ...@@ -20,7 +20,7 @@ Widget buildPage(BuildContext context, int page, int index) {
); );
} }
Widget buildFrame() { Widget buildFrame({ List<int> pages: defaultPages }) {
// 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 this. // to be 800x600. The pageSize constant reflects this.
return new PageableList<int>( return new PageableList<int>(
...@@ -66,7 +66,6 @@ void main() { ...@@ -66,7 +66,6 @@ void main() {
test('PageableList with itemsWrap: true', () { test('PageableList with itemsWrap: true', () {
testWidgets((WidgetTester tester) { testWidgets((WidgetTester tester) {
tester.pumpWidget(new Container());
currentPage = null; currentPage = null;
itemsWrap = true; itemsWrap = true;
tester.pumpWidget(buildFrame()); tester.pumpWidget(buildFrame());
...@@ -79,4 +78,44 @@ void main() { ...@@ -79,4 +78,44 @@ void main() {
expect(currentPage, equals(5)); expect(currentPage, equals(5));
}); });
}); });
test('PageableList with two items', () {
testWidgets((WidgetTester tester) {
currentPage = null;
itemsWrap = true;
tester.pumpWidget(buildFrame(pages: <int>[0, 1]));
expect(currentPage, isNull);
pageLeft(tester);
expect(currentPage, equals(1));
pageRight(tester);
expect(currentPage, equals(0));
pageRight(tester);
expect(currentPage, equals(1));
});
});
test('PageableList with one item', () {
testWidgets((WidgetTester tester) {
currentPage = null;
itemsWrap = true;
tester.pumpWidget(buildFrame(pages: <int>[0]));
expect(currentPage, isNull);
pageLeft(tester);
expect(currentPage, equals(0));
pageRight(tester);
expect(currentPage, equals(0));
pageRight(tester);
expect(currentPage, equals(0));
});
});
test('PageableList with no items', () {
testWidgets((WidgetTester tester) {
currentPage = null;
itemsWrap = true;
tester.pumpWidget(buildFrame(pages: null));
expect(currentPage, isNull);
});
});
} }
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