我想实现如下所示的目标(动画风格并不重要,我正在寻找实现此目的的方法)

但是,所有资源和问题仅解释如何创建项目添加或删除动画。
我当前的代码(我使用 BLoC 模式)
class _MembersPageState extends State<MembersPage> {
@override
Widget build(BuildContext context) {
return BlocProvider<MembersPageBloc>(
create: (context) =>
MembersPageBloc(userRepository: UserRepository.instance)..add(MembersPageShowed()),
child: BlocBuilder<MembersPageBloc, MembersPageState>(
builder: (context, state) {
if (state is MembersPageSuccess) {
return ListView.builder(
itemCount: state.users.length,
itemBuilder: (context, index) {
User user = state.users[index];
return ListTile(
isThreeLine: true,
leading: Icon(Icons.person, size: 36),
title: Text(user.name),
subtitle: Text(user.username),
onTap: () => null,
);
},
);
} else
return Text("I don't care");
},
),
);
}
}
Run Code Online (Sandbox Code Playgroud) 我有实现 ChangeNotifier 的模型
class DataModel with ChangeNotifier{
List<Data> data = List<Data>();
void addData(Data data){
data.add(data);
notifyListeners();
}
}
Run Code Online (Sandbox Code Playgroud)
以及一个监听这些变化的 ListView:
class DataListView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<DataModel>(
builder: (context, model, child) {
return ListView.builder(
itemCount: model.data.length,
itemBuilder: (context, index) {
return Text(model.data[index].value);
},
);
},
);
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止一切顺利,当一个项目添加到模型中的列表时,更改通知会触发 Listview 的重建,我会看到新数据。但是我无法将它与 AnimatedList 而不是 ListView 一起使用。最好我喜欢保持我的模型原样,因为动画是 ui 的问题,而不是我的逻辑。
changenotifier 总是为我提供最新版本的数据,但我真正需要的是“添加项目”或“删除项目”通知。
有没有这样做的最佳实践方法?
我在 flutter 中使用动画列表加载列表类,在添加或删除项目时,动画有效,但当列表最初加载时,动画不起作用。有没有办法在最初加载列表时为项目设置动画。
class AnimationTest extends StatefulWidget {
@override
_AnimationTestState createState() => _AnimationTestState();
}
class _AnimationTestState extends State<AnimationTest> with SingleTickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
);
super.initState();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedList(
key: _listKey,
initialItemCount: 3,
itemBuilder: (BuildContext context, int index, Animation animation) {
return SlideTransition(
position: animation.drive(Tween<Offset>(begin: Offset(1.0, 0.0), end: Offset.zero)
.chain(CurveTween(curve: Curves.decelerate))),
child: Row(
children: <Widget>[
Expanded( …Run Code Online (Sandbox Code Playgroud) 我发现的所有将项目插入 Flutter AnimatedList 的示例都利用 GlobalKey.currentState 告诉 AnimatedList 小部件已插入项目。从列表中删除也是一样。
众所周知,在 Flutter 中 GlobalKey 的 currentState 可能为 null。
就我而言,我正在等待 Firebase 消息通过。当出现该消息被插入到 AnimatedList 的 List 数据中时,如果要遵循为 AnimatedList 显示的流行示例,则将使用分配的 GlobalKey.currentState 来告诉 AnimatedList 新项目的插入位置。
但是,就我而言,当我尝试使用它时, GlobalKey.currentState 为空。
否则我还能用什么?我知道我可以使用 setState 但这会导致完整的小部件刷新,在这种情况下,它显示为屏幕上的闪光,而不是所需的漂亮且流畅的 AnimatedList 插入。
许多人都没有使用 InheritedWidget,但如果这是正确的技术,我无法理解在这种情况下它将如何实现。
/////////
// NOTE: This is close to real code, but consider it pseudocode since it is a cut and paste from the real code less quite a bit of extra stuff I have in there. It certainly will not compile but …Run Code Online (Sandbox Code Playgroud) 我正在尝试实现一个动画列表,
但我对动画不是很熟悉。
我应该插入的内容
位置:animation.drive(),
和
removeItem(_index,(context,animation)=> /// 我应该在这里做什么 ),);
这是代码(仅从“启动应用程序”中进行了一些更改)
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
List<int> _list = [];
final GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>();
void _addItem() {
final int _index = _list.length;
_list.insert(_index,_index);
_listKey.currentState.insertItem(_index);
}
void _removeItem() {
final int _index = _list.length-1;
_listKey.currentState.removeItem(_index,(context,animation)=> /// what I'm supposed to do here
),);
}
@override …Run Code Online (Sandbox Code Playgroud) 我有一个ListView它的排序取决于它的项目状态:Item模型对象有一个bool属性,isActive,并且所有Item值为 的 strue在所有值为 的 s之前排序false。点击一个项目会切换它的isActive状态。设置状态的逻辑不是在列表本身中完成的;相反,它由 BLoC 执行,它也知道如何对项目进行排序。结果,所有列表得到的是一个List<Item>正确排序的流。
目前,结果非常不和谐 - 被点击的项目从它的位置消失并出现在列表中的其他地方,我想让它更平滑,比如可能动画位置变化 - 就像什么ReorderableListView一样,但以编程方式。我不知道该怎么做,我开始胡思乱想,AnimatedList但我不确定这是否适合我的用例 - 它可以为删除和添加设置动画,这不是我真正在做什么(我可以添加一个立即删除,然后添加,但这似乎很复杂)。
这是我到目前为止的代码(简化),它支持动画移除:
class ItemListWidget extends StatelessWidget {
final items = [
'Item A',
'Item B',
'Item C',
'Item D',
'Item E',
];
@override
Widget build(BuildContext context) {
return AnimatedList(
initialItemCount: items.length,
itemBuilder: (context, index, animation) {
final item = items[index];
return ListTile(
title: Text(item),
onTap: …Run Code Online (Sandbox Code Playgroud) 是否可以像 ReorderableListView 一样对 ListView 的顺序更改进行动画处理,但无需用户交互。
例如,意味着几秒钟后 ListView 的顺序会发生变化。所以我有两个包含相同项目但顺序不同的列表。列表一和列表二。
我已经看到了 AnimatedList,但在那里我可以删除或添加动画。我需要像移动动画这样的东西。
有点像 ReorderableListView,但没有用户交互。或者是否可以在 ReorderableListView 中以编程方式替换用户交互?
提前致谢
我试图像在Android中为RecyclerView适配器所做的那样,在AnimatedList上预生成所有更新操作。但是当我要清除所有数据时,我不知道该怎么做。
如果我这样做
setState(() {
_data.clear();
});
Run Code Online (Sandbox Code Playgroud)
然后清除了后备数据,但是GlobalKey的当前状态仍然不知道更改,并且没有任何clear()方法。
补充代码
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(title: Text('Update AnimatedList data')),
body: BodyWidget(),
),
);
}
}
class BodyWidget extends StatefulWidget {
@override
BodyWidgetState createState() {
return new BodyWidgetState();
}
}
class BodyWidgetState extends State<BodyWidget> {
// the GlobalKey is needed to animate the list
final GlobalKey<AnimatedListState> _listKey = GlobalKey();
// backing data
List<String> …Run Code Online (Sandbox Code Playgroud) 如何在Flutter中的AnimatedList中更新数据(添加,删除行)?我可以在ListView中通过更新后备数据并调用来做到这一点setState。例如,
setState(() {
_data.insert(2, 'pig');
});
Run Code Online (Sandbox Code Playgroud)
不过,在AnimatedList中似乎更复杂。
我在 ListView 中使用 Slidable,这样我就可以删除项目。问题是,如果我从列表中删除一个项目,新项目将可滑动打开。这显然不是理想的行为。这是一个屏幕视频,以便更好地理解。
\n我的列表是一个 AnimatedList:
\n\n` child: AnimatedList(\n padding: EdgeInsets.zero,\n shrinkWrap: true,\n key: listKey,\n initialItemCount: widget.month.memories.length,\n itemBuilder: (context, index, animation) {\n return slideIt(\n context,\n widget.month.memories[index],\n index,\n animation,\n );\n },\n ),`\nRun Code Online (Sandbox Code Playgroud)\n这是我的滑动:
\n` Widget slideIt(\n BuildContext context,\n Memory memory,\n int index,\n animation,\n ) {\n return SlideTransition(\n position: Tween<Offset>(\n begin: const Offset(-1, 0),\n end: Offset(0, 0),\n ).animate(\n CurvedAnimation(\n parent: animation,\n curve: Curves.easeIn,\n reverseCurve: Curves.easeOut,\n ),\n ),\n child: Slidable(\n actionPane: SlidableDrawerActionPane(),\n actionExtentRatio: 0.25,\n movementDuration: Duration(milliseconds: 400),\n …Run Code Online (Sandbox Code Playgroud)