如何使用 Flutter Bloc 逃避多个列出的 Widget(按钮)状态管理?

How Can I Escape Multiple Listed Widget (Button) State Management with Flutter Bloc?

我正在使用 Flutter Bloc 管理状态。我有一个清单。当您按下 + 按钮时,它会通过向 API 发送请求来添加到列表中。安装时显示循环进度指示器,完成时显示成功图标。

但是,所有按钮的情况都会发生变化,而不是相关按钮。如何仅更改按下按钮的状态?

return ListView.builder(
    itemCount: state.model.length,
    itemBuilder: (context, index) {
      return ListTile(
          title: Text(
            state.model[index].title ?? "",
            style: TextStyle(fontWeight: FontWeight.w500),
          ),
          subtitle: Text("${state.model[index].subTitle}"),
          trailing: BlocConsumer<CarCubit, CarState>(
              listener: (context, state) {
            if (eatState is CarError) {
              final snackBar = SnackBar(
                content: Text(state.message ?? ""),
              );
              ScaffoldMessenger.of(context).showSnackBar(snackBar);
            }
          }, builder: (context, state) {
            return TextButton(
                onPressed: state is CarInitial
                    ? () {
                        context.read<CarCubit>().addList(
                            CarModel(
                              title: state.model[index].title,
                              category: state.model[index].category,
                              image: state.model[index].image,
                            ));
                      }
                    : null,
                child: carStateWidget(state));
          }));
    });

Widget carStateWidget(CarState state) {
    if (state is CarLoading) {
      return CircularProgressIndicator(
        color: Colors.white,
      );
    } else if (state is CarCompleted) {
      return Icon(
        Icons.done,
        color: Colors.white,
      );
    }
    return Text("+", style: TextStyle(color: Colors.white));
  }

您可以为 CarLoading 状态创建 carId 实例 class 并且在发出它时只需检查此汽车对象的加载按钮的当前 carId(我假设每辆汽车都是一个对象并且有一个carId 实例)匹配从状态接收到的 ID。

类似的东西:

Widget carStateWidget(CarState state, int carId) {  // carId
    if (state is CarLoading && state.carId == carId) {  // check
      return CircularProgressIndicator(
        color: Colors.white,
      );
    } else if (state is CarCompleted) {
      return Icon(
        Icons.done,
        color: Colors.white,
      );
    }
    return Text("+", style: TextStyle(color: Colors.white));
  }

注意,不要使用方法来创建小部件,因为很多原因,即使是 flutter 团队也不推荐这样做,你可以查看 this.

分胜负

创建一个CarWidget有自己的私人腕尺:

  • 添加新元素时,会在 ListView 中添加新的 CarWidget。这个小部件是一个简单的 Row,带有汽车标签和 + 按钮。

  • 当用户按下 + 按钮时,您可以使用 cubit 来请求您的 API,但请注意,此 cubit 是此 CarWidget 实例私有的。这个腕可以初始化成initState.

一个Cubit(或者一个Bloc)是一个状态管理。正如您提到的每个按钮(或行)都必须有自己的状态,因此最好也更容易使其状态尽可能接近小部件。

优点:
1- 一个小部件的状态不可能干扰另一个小部件
2- 您不会构建整棵树,而只会构建相关的小部件。
3- 用户将能够添加多辆汽车,甚至无需等待前一辆汽车完成(这对您的代码来说是不可能的)。