Unverified Commit 5c44057d authored by otto-dev's avatar otto-dev Committed by GitHub

Apply `indexToItemIndex` to indices returned by `findChildIndexCallback` in...

Apply `indexToItemIndex` to indices returned by `findChildIndexCallback` in `SliverAnimatedListState` (#108710)
parent bd0aafac
...@@ -514,7 +514,12 @@ class SliverAnimatedListState extends State<SliverAnimatedList> with TickerProvi ...@@ -514,7 +514,12 @@ class SliverAnimatedListState extends State<SliverAnimatedList> with TickerProvi
return SliverChildBuilderDelegate( return SliverChildBuilderDelegate(
_itemBuilder, _itemBuilder,
childCount: _itemsCount, childCount: _itemsCount,
findChildIndexCallback: widget.findChildIndexCallback, findChildIndexCallback: widget.findChildIndexCallback == null
? null
: (Key key) {
final int? index = widget.findChildIndexCallback!(key);
return index != null ? _indexToItemIndex(index) : null;
},
); );
} }
......
...@@ -357,6 +357,67 @@ void main() { ...@@ -357,6 +357,67 @@ void main() {
expect(find.text('removing'), findsNothing); expect(find.text('removing'), findsNothing);
expect(tester.getTopLeft(find.text('item 0')).dy, 200); expect(tester.getTopLeft(find.text('item 0')).dy, 200);
}); });
testWidgets('passes correctly derived index of findChildIndexCallback to the inner SliverChildBuilderDelegate', (WidgetTester tester) async {
final List<int> items = <int>[0, 1, 2, 3];
final GlobalKey<SliverAnimatedListState> listKey = GlobalKey<SliverAnimatedListState>();
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: CustomScrollView(
slivers: <Widget>[
SliverAnimatedList(
key: listKey,
initialItemCount: items.length,
itemBuilder: (BuildContext context, int index, Animation<double> animation) {
return _StatefulListItem(
key: ValueKey<int>(items[index]),
index: index,
);
},
findChildIndexCallback: (Key key) {
final int index = items.indexOf((key as ValueKey<int>).value);
return index == -1 ? null : index;
},
),
],
),
),
);
// get all list entries in order
final List<Text> listEntries = find.byType(Text).evaluate().map((Element e) => e.widget as Text).toList();
// check that the list is rendered in the correct order
expect(listEntries[0].data, equals('item 0'));
expect(listEntries[1].data, equals('item 1'));
expect(listEntries[2].data, equals('item 2'));
expect(listEntries[3].data, equals('item 3'));
// delete one item
listKey.currentState?.removeItem(0, (BuildContext context, Animation<double> animation) {
return Container();
});
// delete from list
items.removeAt(0);
// reorder list
items.insert(0, items.removeLast());
// render with new list order
await tester.pumpAndSettle();
// get all list entries in order
final List<Text> reorderedListEntries = find.byType(Text).evaluate().map((Element e) => e.widget as Text).toList();
// check that the stateful items of the list are rendered in the order provided by findChildIndexCallback
expect(reorderedListEntries[0].data, equals('item 3'));
expect(reorderedListEntries[1].data, equals('item 1'));
expect(reorderedListEntries[2].data, equals('item 2'));
});
}); });
testWidgets( testWidgets(
...@@ -428,3 +489,25 @@ void main() { ...@@ -428,3 +489,25 @@ void main() {
expect(tester.widget<CustomScrollView>(find.byType(CustomScrollView)).clipBehavior, clipBehavior); expect(tester.widget<CustomScrollView>(find.byType(CustomScrollView)).clipBehavior, clipBehavior);
}); });
} }
class _StatefulListItem extends StatefulWidget {
const _StatefulListItem({
super.key,
required this.index,
});
final int index;
@override
_StatefulListItemState createState() => _StatefulListItemState();
}
class _StatefulListItemState extends State<_StatefulListItem> {
late final int number = widget.index;
@override
Widget build(BuildContext context) {
return Text('item $number');
}
}
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