Merge branch 'feat/update-spl' into feat/message-list-view-shrink-wrap
This commit is contained in:
+8
-6
@@ -391,12 +391,14 @@ void main() {
|
|||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Insert a new opaque OverlayEntry that would prevent the first OverlayEntry
|
// Insert a new opaque OverlayEntry that would prevent the first
|
||||||
// from doing re-layout. Since there's no relayout boundaries in the first
|
// OverlayEntry from doing re-layout. Since there's no relayout boundaries
|
||||||
// OverlayEntry, no dirty RenderObjects in its render subtree can update
|
// in the first OverlayEntry, no dirty RenderObjects in its render subtree
|
||||||
// layout.
|
// can update layout.
|
||||||
final newOverlay =
|
final newOverlay = OverlayEntry(
|
||||||
OverlayEntry(builder: (context) => const SizedBox.expand(), opaque: true);
|
builder: (context) => const SizedBox.expand(),
|
||||||
|
opaque: true,
|
||||||
|
);
|
||||||
tester.state<OverlayState>(find.byType(Overlay)).insert(newOverlay);
|
tester.state<OverlayState>(find.byType(Overlay)).insert(newOverlay);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
|
|||||||
+91
-77
@@ -48,7 +48,10 @@ void main() {
|
|||||||
itemCount: itemCount,
|
itemCount: itemCount,
|
||||||
itemScrollController: itemScrollController,
|
itemScrollController: itemScrollController,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
assert(index >= 0 && index <= itemCount - 1);
|
assert(
|
||||||
|
index >= 0 && index <= itemCount - 1,
|
||||||
|
'index must be in the range of 0 to itemCount - 1',
|
||||||
|
);
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height:
|
height:
|
||||||
variableHeight ? (itemHeight + (index % 13) * 5) : itemHeight,
|
variableHeight ? (itemHeight + (index % 13) * 5) : itemHeight,
|
||||||
@@ -1133,34 +1136,35 @@ void main() {
|
|||||||
}, skip: true);
|
}, skip: true);
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'Jump to 400 at bottom, manually scroll, scroll to 100 at bottom and back',
|
'Jump to 400 at bottom, manually scroll, scroll to 100 at bottom and back',
|
||||||
(WidgetTester tester) async {
|
(WidgetTester tester) async {
|
||||||
final itemScrollController = ItemScrollController();
|
final itemScrollController = ItemScrollController();
|
||||||
final itemPositionsListener = ItemPositionsListener.create();
|
final itemPositionsListener = ItemPositionsListener.create();
|
||||||
await setUpWidgetTest(tester,
|
await setUpWidgetTest(tester,
|
||||||
itemScrollController: itemScrollController,
|
itemScrollController: itemScrollController,
|
||||||
itemPositionsListener: itemPositionsListener);
|
itemPositionsListener: itemPositionsListener);
|
||||||
|
|
||||||
itemScrollController.jumpTo(index: 400, alignment: 1);
|
itemScrollController.jumpTo(index: 400, alignment: 1);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
final listFinder = find.byType(ScrollablePositionedList);
|
final listFinder = find.byType(ScrollablePositionedList);
|
||||||
|
|
||||||
await tester.drag(listFinder, const Offset(0, -screenHeight));
|
await tester.drag(listFinder, const Offset(0, -screenHeight));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
unawaited(itemScrollController.scrollTo(
|
unawaited(itemScrollController.scrollTo(
|
||||||
index: 100, alignment: 1, duration: scrollDuration));
|
index: 100, alignment: 1, duration: scrollDuration));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
unawaited(itemScrollController.scrollTo(
|
unawaited(itemScrollController.scrollTo(
|
||||||
index: 400, alignment: 1, duration: scrollDuration));
|
index: 400, alignment: 1, duration: scrollDuration));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
final itemFinder = find.text('Item 399');
|
final itemFinder = find.text('Item 399');
|
||||||
expect(itemFinder, findsOneWidget);
|
expect(itemFinder, findsOneWidget);
|
||||||
expect(tester.getBottomLeft(itemFinder).dy, screenHeight);
|
expect(tester.getBottomLeft(itemFinder).dy, screenHeight);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
testWidgets('physics', (WidgetTester tester) async {
|
testWidgets('physics', (WidgetTester tester) async {
|
||||||
final itemScrollController = ItemScrollController();
|
final itemScrollController = ItemScrollController();
|
||||||
@@ -1652,70 +1656,71 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'Maintain programmatic and user position (9 half way off top) in page view',
|
'Maintain programmatic and user position (9 half way off top) in page view',
|
||||||
(WidgetTester tester) async {
|
(WidgetTester tester) async {
|
||||||
final itemPositionsListener = ItemPositionsListener.create();
|
final itemPositionsListener = ItemPositionsListener.create();
|
||||||
final itemScrollController = ItemScrollController();
|
final itemScrollController = ItemScrollController();
|
||||||
|
|
||||||
tester.binding.window.devicePixelRatioTestValue = 1.0;
|
tester.binding.window.devicePixelRatioTestValue = 1.0;
|
||||||
tester.binding.window.physicalSizeTestValue =
|
tester.binding.window.physicalSizeTestValue =
|
||||||
const Size(screenWidth, screenHeight);
|
const Size(screenWidth, screenHeight);
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: PageView(
|
home: PageView(
|
||||||
children: [
|
children: [
|
||||||
KeyedSubtree(
|
KeyedSubtree(
|
||||||
key: const PageStorageKey('key'),
|
key: const PageStorageKey('key'),
|
||||||
child: ScrollablePositionedList.builder(
|
child: ScrollablePositionedList.builder(
|
||||||
itemCount: defaultItemCount,
|
itemCount: defaultItemCount,
|
||||||
itemScrollController: itemScrollController,
|
itemScrollController: itemScrollController,
|
||||||
itemBuilder: (context, index) => SizedBox(
|
itemBuilder: (context, index) => SizedBox(
|
||||||
height: itemHeight,
|
height: itemHeight,
|
||||||
child: Text('Item $index'),
|
child: Text('Item $index'),
|
||||||
|
),
|
||||||
|
itemPositionsListener: itemPositionsListener,
|
||||||
),
|
),
|
||||||
itemPositionsListener: itemPositionsListener,
|
|
||||||
),
|
),
|
||||||
),
|
const Center(
|
||||||
const Center(
|
child: Text('Test'),
|
||||||
child: Text('Test'),
|
)
|
||||||
)
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
|
||||||
|
|
||||||
itemScrollController.jumpTo(index: 9);
|
itemScrollController.jumpTo(index: 9);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
expect(tester.getBottomRight(find.text('Item 9')).dy, itemHeight);
|
expect(tester.getBottomRight(find.text('Item 9')).dy, itemHeight);
|
||||||
|
|
||||||
await tester.drag(
|
await tester.drag(
|
||||||
find.byType(ScrollablePositionedList), const Offset(0, -itemHeight));
|
find.byType(ScrollablePositionedList), const Offset(0, -itemHeight));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
final item9Bottom = tester.getBottomRight(find.text('Item 9')).dy;
|
final item9Bottom = tester.getBottomRight(find.text('Item 9')).dy;
|
||||||
expect(item9Bottom, lessThan(itemHeight));
|
expect(item9Bottom, lessThan(itemHeight));
|
||||||
|
|
||||||
await tester.drag(find.byType(PageView), const Offset(-500, 0));
|
await tester.drag(find.byType(PageView), const Offset(-500, 0));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
await tester.drag(find.byType(PageView), const Offset(500, 0));
|
await tester.drag(find.byType(PageView), const Offset(500, 0));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(tester.getBottomRight(find.text('Item 9')).dy, item9Bottom);
|
expect(tester.getBottomRight(find.text('Item 9')).dy, item9Bottom);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
itemPositionsListener.itemPositions.value
|
itemPositionsListener.itemPositions.value
|
||||||
.firstWhere((position) => position.index == 9)
|
.firstWhere((position) => position.index == 9)
|
||||||
.itemLeadingEdge,
|
.itemLeadingEdge,
|
||||||
-(itemHeight / screenHeight) / 2);
|
-(itemHeight / screenHeight) / 2);
|
||||||
expect(
|
expect(
|
||||||
itemPositionsListener.itemPositions.value
|
itemPositionsListener.itemPositions.value
|
||||||
.firstWhere((position) => position.index == 9)
|
.firstWhere((position) => position.index == 9)
|
||||||
.itemTrailingEdge,
|
.itemTrailingEdge,
|
||||||
(itemHeight / screenHeight) / 2);
|
(itemHeight / screenHeight) / 2);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
testWidgets('List with no items', (WidgetTester tester) async {
|
testWidgets('List with no items', (WidgetTester tester) async {
|
||||||
final itemScrollController = ItemScrollController();
|
final itemScrollController = ItemScrollController();
|
||||||
@@ -1746,7 +1751,10 @@ void main() {
|
|||||||
itemScrollController: itemScrollController,
|
itemScrollController: itemScrollController,
|
||||||
itemPositionsListener: itemPositionsListener,
|
itemPositionsListener: itemPositionsListener,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
assert(index >= 0 && index <= itemCount - 1);
|
assert(
|
||||||
|
index >= 0 && index <= itemCount - 1,
|
||||||
|
'index must be in the range of 0 to itemCount - 1',
|
||||||
|
);
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: itemHeight,
|
height: itemHeight,
|
||||||
child: Text('Item $index'),
|
child: Text('Item $index'),
|
||||||
@@ -1788,7 +1796,10 @@ void main() {
|
|||||||
initialScrollIndex: min(100, itemCount - 1),
|
initialScrollIndex: min(100, itemCount - 1),
|
||||||
itemCount: itemCount,
|
itemCount: itemCount,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
assert(index >= 0 && index <= itemCount - 1);
|
assert(
|
||||||
|
index >= 0 && index <= itemCount - 1,
|
||||||
|
'index must be in the range of 0 to itemCount - 1',
|
||||||
|
);
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: itemHeight,
|
height: itemHeight,
|
||||||
child: Text('Item $index'),
|
child: Text('Item $index'),
|
||||||
@@ -1827,7 +1838,10 @@ void main() {
|
|||||||
initialScrollIndex: itemCount - 1,
|
initialScrollIndex: itemCount - 1,
|
||||||
itemCount: itemCount,
|
itemCount: itemCount,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
assert(index >= 0 && index <= itemCount - 1);
|
assert(
|
||||||
|
index >= 0 && index <= itemCount - 1,
|
||||||
|
'index must be in the range of 0 to itemCount - 1',
|
||||||
|
);
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: itemHeight,
|
height: itemHeight,
|
||||||
child: Text('Item $index'),
|
child: Text('Item $index'),
|
||||||
|
|||||||
+68
-64
@@ -31,12 +31,13 @@ void main() {
|
|||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
// Use flex layout to ensure that the minimum height is not limited to screenHeight
|
// Use flex layout to ensure that the minimum height is not limited to
|
||||||
|
// screenHeight.
|
||||||
home: Column(children: [
|
home: Column(children: [
|
||||||
// Use Constrained to make max height not more than screenHeight
|
// Use Constrained to make max height not more than screenHeight
|
||||||
ConstrainedBox(
|
ConstrainedBox(
|
||||||
constraints:
|
constraints: const BoxConstraints(
|
||||||
const BoxConstraints(maxHeight: screenHeight, maxWidth: screenWidth),
|
maxHeight: screenHeight, maxWidth: screenWidth),
|
||||||
child: PositionedList(
|
child: PositionedList(
|
||||||
key: key,
|
key: key,
|
||||||
itemCount: itemCount,
|
itemCount: itemCount,
|
||||||
@@ -292,73 +293,75 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'List positioned with 5 at top then scroll up 2 programatically and shrink wrap',
|
'''List positioned with 5 at top then scroll up 2 programatically and shrink wrap''',
|
||||||
(WidgetTester tester) async {
|
(WidgetTester tester) async {
|
||||||
final scrollController = ScrollController();
|
final scrollController = ScrollController();
|
||||||
await setUpWidgetTest(tester,
|
await setUpWidgetTest(tester,
|
||||||
topItem: 5, scrollController: scrollController);
|
topItem: 5, scrollController: scrollController);
|
||||||
|
|
||||||
scrollController.jumpTo(-2 * itemHeight);
|
scrollController.jumpTo(-2 * itemHeight);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
expect(find.text('Item 2'), findsNothing);
|
expect(find.text('Item 2'), findsNothing);
|
||||||
expect(find.text('Item 3'), findsOneWidget);
|
expect(find.text('Item 3'), findsOneWidget);
|
||||||
expect(find.text('Item 12'), findsOneWidget);
|
expect(find.text('Item 12'), findsOneWidget);
|
||||||
expect(find.text('Item 13'), findsNothing);
|
expect(find.text('Item 13'), findsNothing);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
itemPositionsNotifier.itemPositions.value
|
itemPositionsNotifier.itemPositions.value
|
||||||
.firstWhere((position) => position.index == 2)
|
.firstWhere((position) => position.index == 2)
|
||||||
.itemLeadingEdge,
|
.itemLeadingEdge,
|
||||||
-1 / 10);
|
-1 / 10);
|
||||||
expect(
|
expect(
|
||||||
itemPositionsNotifier.itemPositions.value
|
itemPositionsNotifier.itemPositions.value
|
||||||
.firstWhere((position) => position.index == 3)
|
.firstWhere((position) => position.index == 3)
|
||||||
.itemLeadingEdge,
|
.itemLeadingEdge,
|
||||||
0);
|
0);
|
||||||
expect(
|
expect(
|
||||||
itemPositionsNotifier.itemPositions.value
|
itemPositionsNotifier.itemPositions.value
|
||||||
.firstWhere((position) => position.index == 12)
|
.firstWhere((position) => position.index == 12)
|
||||||
.itemTrailingEdge,
|
.itemTrailingEdge,
|
||||||
1);
|
1);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'List positioned with 5 at top then scroll down 20 programatically and shrink wrap',
|
'''List positioned with 5 at top then scroll down 20 programatically and shrink wrap''',
|
||||||
(WidgetTester tester) async {
|
(WidgetTester tester) async {
|
||||||
final scrollController = ScrollController();
|
final scrollController = ScrollController();
|
||||||
await setUpWidgetTest(tester,
|
await setUpWidgetTest(tester,
|
||||||
topItem: 5, scrollController: scrollController);
|
topItem: 5, scrollController: scrollController);
|
||||||
|
|
||||||
scrollController.jumpTo(itemHeight * 20);
|
scrollController.jumpTo(itemHeight * 20);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
itemPositionsNotifier.itemPositions.value
|
itemPositionsNotifier.itemPositions.value
|
||||||
.firstWhere((position) => position.index == 23)
|
.firstWhere((position) => position.index == 23)
|
||||||
.itemLeadingEdge,
|
.itemLeadingEdge,
|
||||||
-2 / 10);
|
-2 / 10);
|
||||||
expect(
|
expect(
|
||||||
itemPositionsNotifier.itemPositions.value
|
itemPositionsNotifier.itemPositions.value
|
||||||
.firstWhere((position) => position.index == 24)
|
.firstWhere((position) => position.index == 24)
|
||||||
.itemLeadingEdge,
|
.itemLeadingEdge,
|
||||||
-1 / 10);
|
-1 / 10);
|
||||||
expect(
|
expect(
|
||||||
itemPositionsNotifier.itemPositions.value
|
itemPositionsNotifier.itemPositions.value
|
||||||
.firstWhere((position) => position.index == 25)
|
.firstWhere((position) => position.index == 25)
|
||||||
.itemLeadingEdge,
|
.itemLeadingEdge,
|
||||||
0);
|
0);
|
||||||
expect(
|
expect(
|
||||||
itemPositionsNotifier.itemPositions.value
|
itemPositionsNotifier.itemPositions.value
|
||||||
.firstWhere((position) => position.index == 4)
|
.firstWhere((position) => position.index == 4)
|
||||||
.itemLeadingEdge,
|
.itemLeadingEdge,
|
||||||
-21 / 10);
|
-21 / 10);
|
||||||
expect(
|
expect(
|
||||||
itemPositionsNotifier.itemPositions.value
|
itemPositionsNotifier.itemPositions.value
|
||||||
.firstWhere((position) => position.index == 5)
|
.firstWhere((position) => position.index == 5)
|
||||||
.itemLeadingEdge,
|
.itemLeadingEdge,
|
||||||
-20 / 10);
|
-20 / 10);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'List positioned with 5 at top and initial scroll offset and shrink wrap',
|
'List positioned with 5 at top and initial scroll offset and shrink wrap',
|
||||||
@@ -424,7 +427,8 @@ void main() {
|
|||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
// Use flex layout to ensure that the minimum height is not limited to screenHeight
|
// Use flex layout to ensure that the minimum height is not limited to
|
||||||
|
// screenHeight.
|
||||||
home: PositionedList(
|
home: PositionedList(
|
||||||
itemCount: 5,
|
itemCount: 5,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
|
|||||||
+4
-3
@@ -27,12 +27,13 @@ void main() {
|
|||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
// Use flex layout to ensure that the minimum height is not limited to screenHeight
|
// Use flex layout to ensure that the minimum height is not limited to
|
||||||
|
// screenHeight.
|
||||||
home: Column(children: [
|
home: Column(children: [
|
||||||
// Use Constrained to make max height not more than screenHeight
|
// Use Constrained to make max height not more than screenHeight
|
||||||
ConstrainedBox(
|
ConstrainedBox(
|
||||||
constraints:
|
constraints: const BoxConstraints(
|
||||||
const BoxConstraints(maxHeight: screenHeight, maxWidth: screenWidth),
|
maxHeight: screenHeight, maxWidth: screenWidth),
|
||||||
child: ScrollablePositionedList.builder(
|
child: ScrollablePositionedList.builder(
|
||||||
itemCount: itemCount,
|
itemCount: itemCount,
|
||||||
initialScrollIndex: initialIndex,
|
initialScrollIndex: initialIndex,
|
||||||
|
|||||||
Reference in New Issue
Block a user