隐式动画可重排列表
一个Flutter ListView,它使用MyersDiff算法隐式计算两个列表之间的变化,并为您在它们之间进行动画。ImplicitlyAnimatedReorderableList为列表项添加了重排支持,并具有完全自定义的动画。
一个Flutter ListView,它在两个列表的变化之间隐式动画,并支持重排其列表项。

点击这里查看完整示例。
安装
将其添加到您的pubspec.yaml文件中
dependencies:
implicitly_animated_reorderable_list: ^0.1.5
从命令行安装软件包
flutter packages get
用法
该软件包包含两个ListViews:ImplicitlyAnimatedList是基类,它为项目插入、删除以及更新提供隐式动画,而ImplicitlyAnimatedReorderableList扩展了ImplicitlyAnimatedList并为列表项添加了重排支持。请参阅下面的示例了解如何使用它们。
ImplicitlyAnimatedList
ImplicitlyAnimatedList基于AnimatedList,并使用MyersDiff算法计算两个列表之间的差异,并为您在AnimatedListState上调用insertItem和removeItem。
示例
// Specify the generic type of the data in the list.
ImplicitlyAnimatedList<MyGenericType>(
// The current items in the list.
items: items,
// Called by the DiffUtil to decide whether two object represent the same item.
// For example, if your items have unique ids, this method should check their id equality.
areItemsTheSame: (a, b) => a.id == b.id,
// Called, as needed, to build list item widgets.
// List items are only built when they're scrolled into view.
itemBuilder: (context, animation, item, index) {
// Specifiy a transition to be used by the ImplicitlyAnimatedList.
// In this case a custom transition.
return SizeFadeTranstion(
sizeFraction: 0.7,
curve: Curves.easeInOut,
animation: animation,
child: Text(item.name),
);
},
// An optional builder when an item was removed from the list.
// If not specified, the List uses the itemBuilder with
// the animation reversed.
removedItemBuilder: (context, animation, oldItem) {
return FadeTransition(
opacity: animation,
child: Text(oldItem.name),
);
},
);
请注意,由于
AnimatedList不支持项目移动,因此移动是通过从旧索引中删除项目并将其插入新索引来处理的。
ImplicitlyAnimatedReorderableList
ImplicitlyAnimatedReorderableList基于ImplicitlyAnimatedList,并为列表添加了重排支持。
示例
ImplicitlyAnimatedReorderableList<MyGenericType>(
items: items,
areItemsTheSame: (oldItem, newItem) => oldItem.id == newItem.id,
onReorderFinished: (item, from, to, newItems) {
// Remember to update the underlying data when the list has been
// reordered.
setState(() {
items
..clear()
..addAll(newItems);
});
},
itemBuilder: (context, itemAnimation, item, index) {
// Each item must be wrapped in a Reorderable widget.
return Reorderable(
// Each item must have an unique key.
key: ValueKey(item),
// The animation of the Reorderable builder can be used to
// change to appearance of the item between dragged and normal
// state. For example to add elevation when the item is being dragged.
// This is not to be confused with the animation of the itemBuilder.
// Implicit animations (like AnimatedContainer) are sadly not yet supported.
builder: (context, dragAnimation, inDrag) {
final t = dragAnimation.value;
final elevation = lerpDouble(0, 8, t);
final color = Color.lerp(Colors.white, Colors.white.withOpacity(0.8), t);
return SizeFadeTranstion(
sizeFraction: 0.7,
curve: Curves.easeInOut,
animation: itemAnimation,
child: Material(
color: color,
elevation: elevation,
type: MaterialType.transparency,
child: ListTile(
title: Text(item.name),
// The child of a Handle can initialize a drag/reorder.
// This could for example be an Icon or the whole item itself. You can
// use the delay parameter to specify the duration for how long a pointer
// must press the child, until it can be dragged.
trailing: Handle(
delay: const Duration(milliseconds: 100),
child: Icon(
Icons.list,
color: Colors.grey,
),
),
),
),
);
},
);
},
);
有关更深入的示例,请点击这里。
注意事项
请注意,此软件包仍处于非常早期阶段,尚未进行充分测试以保证稳定性。
另请注意,计算两个非常大的列表之间的差异可能需要大量时间(尽管计算是在后台隔离中进行的)。
致谢
ImplicitlyAnimatedList使用的diff算法是由Dawid Bota在GitLab上编写的。
路线图
您可以查看路线图,了解我正在开发或计划在未来版本中实现的功能。