mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Support an empty PageableList
This commit is contained in:
parent
a9f0044e29
commit
fcfcfd56d2
@ -256,7 +256,6 @@ class _HomogeneousPageViewportElement extends _ViewportBaseElement<HomogeneousPa
|
||||
// doing our own layout.)
|
||||
BuildableElement.lockState(() {
|
||||
double itemExtent = widget.direction == ScrollDirection.vertical ? constraints.maxHeight : constraints.maxWidth;
|
||||
double contentExtent = itemExtent * widget.itemCount;
|
||||
double offset;
|
||||
if (widget.startOffset <= 0.0 && !widget.itemsWrap) {
|
||||
_layoutFirstIndex = 0;
|
||||
@ -265,9 +264,10 @@ class _HomogeneousPageViewportElement extends _ViewportBaseElement<HomogeneousPa
|
||||
_layoutFirstIndex = widget.startOffset.floor();
|
||||
offset = -((widget.startOffset * itemExtent) % itemExtent);
|
||||
}
|
||||
if (itemExtent < double.INFINITY) {
|
||||
_layoutItemCount = ((contentExtent - offset) / contentExtent).ceil();
|
||||
if (widget.itemCount != null && !widget.itemsWrap)
|
||||
if (itemExtent < double.INFINITY && widget.itemCount != null) {
|
||||
final double contentExtent = itemExtent * widget.itemCount;
|
||||
_layoutItemCount = contentExtent == 0.0 ? 0 : ((contentExtent - offset) / contentExtent).ceil();
|
||||
if (!widget.itemsWrap)
|
||||
_layoutItemCount = math.min(_layoutItemCount, widget.itemCount - _layoutFirstIndex);
|
||||
} else {
|
||||
assert(() {
|
||||
|
||||
@ -148,15 +148,15 @@ class PageableListState<T, Config extends PageableList<T>> extends ScrollableSta
|
||||
bool get snapScrollOffsetChanges => config.itemsSnapAlignment == ItemsSnapAlignment.item;
|
||||
|
||||
double snapScrollOffset(double newScrollOffset) {
|
||||
double previousItemOffset = newScrollOffset.floorToDouble();
|
||||
double nextItemOffset = newScrollOffset.ceilToDouble();
|
||||
final double previousItemOffset = newScrollOffset.floorToDouble();
|
||||
final double nextItemOffset = newScrollOffset.ceilToDouble();
|
||||
return (newScrollOffset - previousItemOffset < 0.5 ? previousItemOffset : nextItemOffset)
|
||||
.clamp(scrollBehavior.minScrollOffset, scrollBehavior.maxScrollOffset);
|
||||
}
|
||||
|
||||
Future _flingToAdjacentItem(Offset velocity) {
|
||||
double scrollVelocity = scrollDirectionVelocity(velocity);
|
||||
double newScrollOffset = snapScrollOffset(scrollOffset + scrollVelocity.sign)
|
||||
final double scrollVelocity = scrollDirectionVelocity(velocity);
|
||||
final double newScrollOffset = snapScrollOffset(scrollOffset + scrollVelocity.sign)
|
||||
.clamp(snapScrollOffset(scrollOffset - 0.5), snapScrollOffset(scrollOffset + 0.5));
|
||||
return scrollTo(newScrollOffset, duration: config.duration, curve: config.curve)
|
||||
.then(_notifyPageChanged);
|
||||
@ -177,9 +177,9 @@ class PageableListState<T, Config extends PageableList<T>> extends ScrollableSta
|
||||
}
|
||||
|
||||
List<Widget> buildItems(BuildContext context, int start, int count) {
|
||||
List<Widget> result = new List<Widget>();
|
||||
int begin = config.itemsWrap ? start : math.max(0, start);
|
||||
int end = config.itemsWrap ? begin + count : math.min(begin + count, config.items.length);
|
||||
final List<Widget> result = new List<Widget>();
|
||||
final int begin = config.itemsWrap ? start : math.max(0, start);
|
||||
final int end = config.itemsWrap ? begin + count : math.min(begin + count, itemCount);
|
||||
for (int i = begin; i < end; ++i)
|
||||
result.add(config.itemBuilder(context, config.items[i % itemCount], i));
|
||||
assert(result.every((Widget item) => item.key != null));
|
||||
|
||||
@ -7,7 +7,7 @@ import 'package:flutter/widgets.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
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;
|
||||
bool itemsWrap = false;
|
||||
|
||||
@ -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)
|
||||
// to be 800x600. The pageSize constant reflects this.
|
||||
return new PageableList<int>(
|
||||
@ -66,7 +66,6 @@ void main() {
|
||||
|
||||
test('PageableList with itemsWrap: true', () {
|
||||
testWidgets((WidgetTester tester) {
|
||||
tester.pumpWidget(new Container());
|
||||
currentPage = null;
|
||||
itemsWrap = true;
|
||||
tester.pumpWidget(buildFrame());
|
||||
@ -79,4 +78,44 @@ void main() {
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user