diffutil_sliverlist 0.5.0-nullsafety.0 diffutil_sliverlist: ^0.5.0-nullsafety.0 copied to clipboard
A SliverList that implicitly animates changes using diffutil.dart.
diffutil_sliverlist #
A SliverList that implicitly animates changes.
It supports two use cases:
Animating changes from a list of widgets with unique keys #
When you have a list of Widgets and can give each Widget a unique key, you can use DiffUtilSliverList.fromKeyedWidgetList
.
See the example code:
class _ExpandableListsState extends State<ExpandableLists> {
bool expanded = false;
@override
Widget build(BuildContext context) {
return DiffUtilSliverList.fromKeyedWidgetList(
children: [
ListTile(
key: Key("1"),
title: Text("first"),
trailing: Icon(Icons.chevron_right),
),
ListTile(
key: Key("2"),
title: Text("second"),
trailing: Icon(Icons.chevron_right),
),
if (this.expanded)
for (int i = 3; i < 6; i++)
ListTile(
key: Key(i.toString()),
title: Text("index: $i"),
trailing: Icon(Icons.chevron_right),
),
ListTile(
key: Key("expand_collapse"),
onTap: () => setState(() {
expaned = !expaned;
}),
title: Text(expanded ? "collapse" : "expand", style: TextStyle(fontWeight: FontWeight.bold),),
trailing: Icon(expanded ? Icons.expand_less : Icons.expand_more),
)
],
insertAnimationBuilder: (context, animation, child) => FadeTransition(
opacity: animation,
child: child,
),
removeAnimationBuilder: (context, animation, child) => FadeTransition(
opacity: animation,
child: SizeTransition(
sizeFactor: animation,
axisAlignment: 0,
child: child,
),
),
);
}
}
And the result:
Building Widgets from a list of data objects that implement == #
Example:
Widget build(BuildContext context) {
return CustomScrollView(
slivers: [
DiffUtilSliverList<int>(
items: list,
builder: (context, item) =>
Container(
color: colors[item % colors.length],
height: 48,
width: double.infinity,
),
insertAnimationBuilder: (context, animation, child) =>
FadeTransition(
opacity: animation,
child: child,
),
removeAnimationBuilder: (context, animation, child) =>
SizeTransition(
sizeFactor: animation,
child: child,
),
removeAnimationDuration: const Duration(milliseconds: 3000),
insertAnimationDuration: const Duration(milliseconds: 1200),
),
],
);
}
If list
changes, the list will automatically animate new/removed items:
If the items don't implement ==
correctly, you can pass your own equalityChecker
.
How to use #
Don't mutate the list passed into DiffUtilSliverList yourself #
The widget works by comparing the old list with the new list.
If you have a List<int> list = [1,2,3]
, pass this to
DiffUtilSliverList<int>(items: list, ...)
,
and then use something like
setState(() {
list.add(4);
});
this is not going to work, since you mutated the list and now DiffUtil can't compare the two states of the lists anymore. either copy the list before mutation:
setState(() {
list = List.from(list); // copy the old list
list.add(4);
});
Or just copy the list before passing it to DiffUtilSliverList:
DiffUtilSliverList<int>(items: List.from(list), ...)
,
Mutability #
DiffUtilSliverList operates as if it owns the passed list and mutates the old list it during calculating which items to animate.
This means that the list passed into DiffUtilSliverList needs to be mutable and growable.
So if you first use it with the list [1,2,3]
, and then with the list [1,2,3,4]
,
it will mutate the fist list with to contents [1,2,3]
.
Normally, this should not be a problem, as the list is outdated anyway, but if this is a problem in your use case,
copy the list before passing it to DiffUtilSliverList.