flutter - Flutter AnimatedList 与提供者模式
问题描述
我有实现 ChangeNotifier 的模型
class DataModel with ChangeNotifier{
List<Data> data = List<Data>();
void addData(Data data){
data.add(data);
notifyListeners();
}
}
和一个监听这些变化的 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);
},
);
},
);
}
}
到目前为止一切顺利,当将项目添加到模型中的列表时,更改通知会触发 Listview 的重建,我会看到新数据。但是我无法将其与 AnimatedList 而不是 ListView 一起使用。最好 id 喜欢保持我的模型原样,因为动画是 ui 的关注点,而不是我的逻辑关注点。
changenotifier 总是为我提供最新版本的数据,但我真正需要的是“添加项目”或“删除项目”通知。
有没有这样做的最佳实践方法?
解决方案
这是我试验的结果。这是一个 Riverpod 版本,但我认为供应商也是如此。
有两点。
- 在使用 AnimatedList 的小部件的父小部件中初始化状态。
- 使用 async 异步添加/删除 AnimatedList 和添加/删除状态。
主要.dart
import 'package:animatedlist_riverpod_sample/provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:hooks_riverpod/all.dart';
void main() {
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Home(),
);
}
}
class Home extends HookWidget {
const Home({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
final todoList = useProvider(todoListProvider.state);
return Scaffold(appBar: AppBar(title: Text('Todo[${todoList.length}]')), body: TodoListView());
}
}
class TodoListView extends HookWidget {
TodoListView({Key key}) : super(key: key);
final GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>();
final todoList = useProvider(todoListProvider.state);
@override
Widget build(BuildContext context) {
return AnimatedList(
key: _listKey,
initialItemCount: todoList.length,
itemBuilder: (context, index, animation) =>
_buildItem(todoList[index], animation, index, context),
);
}
Slidable _buildItem(Todo todo, Animation<double> animation, int index, BuildContext context) {
return Slidable(
actionPane: SlidableDrawerActionPane(),
child: SizeTransition(
sizeFactor: animation,
axis: Axis.vertical,
child: ListTile(title: Text(todo.description), subtitle: Text(todo.id), onTap: () => {})),
secondaryActions: <Widget>[
IconSlideAction(
caption: 'Delete',
color: Colors.red,
icon: Icons.delete,
onTap: () {
_listKey.currentState.removeItem(
index, (context, animation) => _buildItem(todo, animation, index, context),
duration: Duration(milliseconds: 200));
_removeItem(context, todo);
},
),
],
);
}
void _removeItem(BuildContext context, Todo todo) async {
await Future.delayed(
Duration(milliseconds: 200), () => context.read(todoListProvider).remove(todo));
}
}
提供者.dart
import 'package:hooks_riverpod/all.dart';
final todoListProvider = StateNotifierProvider<TodoList>((ref) {
return TodoList([
Todo(id: '0', description: 'Todo1'),
Todo(id: '1', description: 'Todo2'),
Todo(id: '2', description: 'Todo3'),
]);
});
class Todo {
Todo({
this.id,
this.description,
});
final String id;
final String description;
}
class TodoList extends StateNotifier<List<Todo>> {
TodoList([List<Todo> initialTodos]) : super(initialTodos ?? []);
void add(String description) {
state = [
...state,
Todo(description: description),
];
}
void remove(Todo target) {
state = state.where((todo) => todo.id != target.id).toList();
}
}
示例存储库在这里。
推荐阅读
- reactjs - React Material-UI 表单处理
- javascript - 不变违规:“main”尚未注册
- java - Eclipse 错误:无法创建 Java 虚拟机。发生了致命异常。程序将会退出
- php - 传递给 Symfony\Bridge\Doctrine\Form\ChoiceList\IdReader::getIdValue() 的参数 1 必须是一个对象或 null,int 给定
- ipfs - ipfs.add 不适用于 ipfs 客户端 v44.3.0 我该如何解决这个问题?
- docker - 无法将 github 公共存储库克隆到 Dockerfile 的运行顺序中
- python - 如果列表理解中的条件似乎不起作用,则复合
- db2 - DB2 中两列之间的模式比较
- python - 请解释 python -> tuple(random.randrange(BOARD_SIZE[i]) for i in (0,1))
- python - 如何从来自 numpy 数组的循环中获取元素的索引?