如何使用 Bloc/Cubit 在 Flutter 中更新列表?

问题描述

我的 UI 包含一个对象表苹果
表格中的每个单元格:

我的应用程序的主页正在调用以下小部件以从 API加载苹果列表。而且ADDDELETE 函数与相同的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就有了苹果列表,可以正确显示网格了。

但现在我有两个问题:

  1. 当我按下 ADD 按钮或 DELETE 按钮时,所有应用程序都会重建,而实际上我可以重新绘制单元格。但我不知道如何避免这种情况,因为我还需要向应用程序传达苹果列表实际上已更改的信息。我不想重建整个 UI,因为它看起来效率低下,因为我的页面上实际更改的只是选定的单元格。

  2. 当我按下 ADD 按钮或 DELETE 按钮时,我想显示一个替换按钮的圆形进度指示器(同时等待 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));
    }
  }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)