我的 UI 由一个对象表Apples组成。
表格中的每个单元格:
- 如果该单元格不存在苹果,则有一个添加按钮
- 它显示苹果并有一个删除按钮,如果苹果存在
我的应用程序的主页正在调用以下小部件以从API加载苹果列表。并且ADD和DELETE函数也与相同的API进行通信以添加和删除苹果。
class ApplesLoader extends StatefulWidget {
@override
_ApplesLoaderState createState() => _ApplesLoaderState();
}
class _ApplesLoaderState extends State<ApplesLoader> {
@override
void initState() {
super.initState();
BlocProvider.of<ApplesCubit>(context).getAll();
}
@override
Widget build(BuildContext context) {
return BlocConsumer<ApplesCubit, ApplesState>(
listener: ...,
builder: (ctx, state) {
if (!(state is ApplesLoaded)) {
return circularProgressIndicator;
}
return ApplesViewer(state.Apples);
},
);
}
}
所以之后ApplesViewer就有了苹果列表,可以正确显示网格。
但是现在我有两个问题:
当我按下添加按钮或删除按钮时,所有应用程序都被重建,而我实际上可以重新绘制单元格。但我不知道如何避免这种情况,因为我还需要与应用程序沟通苹果列表实际上已更改。我不想重建整个 UI,因为它似乎效率低下,因为我的页面上实际更改的只是选定的单元格。
当我按下添加按钮或删除按钮时,我想显示一个替换按钮的圆形进度指示器(同时等待 API 实际创建/删除苹果)。但是当列表发生变化时,所有的应用程序都会被重建。所以,我不确定如何实现这种期望的行为。
你能帮我解决这两个问题吗?
或者建议我改变基础设施,以防我在处理这个问题时犯了一些错误?
如果需要,这是ApplesCubit的代码
class ApplesCubit extends Cubit<ApplesState> {
final ApplesRepository _repository;
ApplesCubit(this._repository) : super(ApplesLoading());
Future<void> getAll() async {
try {
final apples = await _repository.getAll();
emit(ApplesLoaded(List<Apple>.from(apples)));
} on DataError catch (e) {
emit(ApplesError(e));
}
}
Future<void> create(List<Apple> apples, Apple appleToAdd) async {
try {
final newApple = await _repository.create(appleToAdd);
final updatedApples = List<Apple>.from(apples)..add(newApple);
emit(ApplesLoaded(updatedApples));
} on DataError catch (e) {
emit(ApplesError(e));
}
}
Future<void> delete(List<Apple> Appless, Apple appleToDelete) async {
try {
await _repository.deleteApples(appleToDelete);
final updatedApples = List<Apple>.from(Appless)..remove(appleToDelete);
emit(ApplesLoaded(updatedApples));
} on DataError catch (e) {
emit(ApplesError(e));
}
}
}