Flutter block小部件不同时侦听和生成

4ioopgfo  于 2023-05-30  发布在  Flutter
关注(0)|答案(1)|浏览(123)

我已经安装了bloc_concurrency来使我的区块能够并发调用。我遇到的问题是,当我调用DeleteFriendFetched而没有等待它完成循环时,我再次调用。小部件BlocConsumer只能侦听第一次调用并根据发出的状态进行构建,第二次调用的emmited状态被忽略,但API成功返回响应。如何让我的widget同时生成?

class DeleteFriendBloc extends Bloc<DeleteFriendEvent, DeleteFriendState> {
  final FriendRepository friendRepository;

  DeleteFriendBloc({required this.friendRepository}) : super(DeleteFriendInitial()) {
    on<DeleteFriendFetched>((event, emit) async {
      emit(DeleteFriendLoading(event.userId));
      try {
        final response = await friendRepository.deleteFriend(event.userId);
        emit(DeleteFriendSuccess(response, event.userId));
      } catch (e) {
        emit(DeleteFriendFailure(e.toString()));
      }
    }, transformer: concurrent());
  }
}

// Event
class DeleteFriendEvent extends Equatable {
  const DeleteFriendEvent();

  @override
  List<Object> get props => [];
}

class DeleteFriendFetched extends DeleteFriendEvent {
  final String userId;

  const DeleteFriendFetched({required this.userId});

  @override
  List<Object> get props => [userId];
}

// State
abstract class DeleteFriendState extends Equatable {
  const DeleteFriendState();

  @override
  List<Object> get props => [];
}

class DeleteFriendInitial extends DeleteFriendState {}

class DeleteFriendLoading extends DeleteFriendState {
  final String userId;

  const DeleteFriendLoading(this.userId);
}

class DeleteFriendSuccess extends DeleteFriendState {
  final DeleteFriend response;
  final String userId;

  const DeleteFriendSuccess(this.response, this.userId);
}

class DeleteFriendFailure extends DeleteFriendState {
  final String message;

  const DeleteFriendFailure(this.message);

  @override
  List<Object> get props => [message];
}

我的小部件列表

BlocConsumer<DeleteFriendBloc, DeleteFriendState>(
      key: UniqueKey(),
      listenWhen: (context, state) {
        return state is DeleteFriendFailure;
      },
      listener: (context, state) {
        if (state is DeleteFriendFailure) {
          Helper().handleStateFailure(state.message, context);
        }
      },
      buildWhen: (context, state) {
        return (state is DeleteFriendLoading && state.userId == user.userId) ||
            (state is DeleteFriendSuccess && state.userId == user.userId) ;
      },
      builder: (context, state) {
        if (state is DeleteFriendLoading && state.userId == user.userId) {
          return SizedBox(
            height: 30,
            width: 30,
            child: CircularProgressIndicator(
              color: Theme.of(context).brightness == Brightness.light
                  ? AppColor.defaultBlack
                  : AppColor.defaultWhite,
            ),
          );
        } else if (state is DeleteFriendSuccess && state.userId == user.userId) {
          return const Text("Deleted");
        }
        return SizedBox(
          height: 35,
          width: 35,
          child: ElevatedButton(
            onPressed: () {
              showDialog(
                context: context,
                builder: (BuildContext context) {
                  return AlertDialog(
                    title: const Text('Remove fiend?'),
                    content: Text('Are you sure you want to remove ${user.name} from your friend?'),
                    actions: <Widget>[
                      ElevatedButton(
                        onPressed: () {
                          Navigator.of(context).pop();
                          context.read<DeleteFriendBloc>().add(DeleteFriendFetched(userId: user.userId));
                        },
                        child: const Text('Remove')
                      ),
                      OutlinedButton(
                        onPressed: () {
                          Navigator.of(context).pop();
                        },
                        child: const Text('Cancel')
                      ),
                    ],
                  );
                },
              );
            },
            style: ElevatedButton.styleFrom(
              padding: EdgeInsets.zero,
              backgroundColor: Theme.of(context).brightness == Brightness.light
                  ? AppColor.defaultWhite
                  : AppColor.defaultLightBlack,
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(20),
              ),
            ),
            child: Icon(
              Icons.close,
              color: Theme.of(context).brightness == Brightness.light
                  ? AppColor.defaultBlack
                  : AppColor.defaultWhite,
            )
          )
        );
      },
    );
sd2nnvve

sd2nnvve1#

您遇到的问题是由于Flutter中***BlocConsumer***小部件的行为造成的。默认情况下,***BlocConsumer***widget只监听状态的第一次发射,忽略后续发射,直到widget重新构建。但是,您希望为状态的每次发射同时构建小部件。
将***BlocConsumer***小部件替换为***BlocBuilder***小部件。***BlocBuilder***小部件会在每次有新的状态发射时重新构建自己。

BlocBuilder<DeleteFriendBloc, DeleteFriendState>(
  builder: (context, state) {
    if (state is DeleteFriendLoading && state.userId == user.userId) {
      return SizedBox(
        height: 30,
        width: 30,
        child: CircularProgressIndicator(
          color: Theme.of(context).brightness == Brightness.light
              ? AppColor.defaultBlack
              : AppColor.defaultWhite,
        ),
      );
    } else if (state is DeleteFriendSuccess && state.userId == user.userId) {
      return const Text("Deleted");
    }
    return SizedBox(
      height: 35,
      width: 35,
      child: ElevatedButton(
        onPressed: () {
          showDialog(
            context: context,
            builder: (BuildContext context) {
              return AlertDialog(
                title: const Text('Remove friend?'),
                content: Text('Are you sure you want to remove ${user.name} from your friend list?'),
                actions: <Widget>[
                  ElevatedButton(
                    onPressed: () {
                      Navigator.of(context).pop();
                      context.read<DeleteFriendBloc>().add(DeleteFriendFetched(userId: user.userId));
                    },
                    child: const Text('Remove')
                  ),
                  OutlinedButton(
                    onPressed: () {
                      Navigator.of(context).pop();
                    },
                    child: const Text('Cancel')
                  ),
                ],
              );
            },
          );
        },
        style: ElevatedButton.styleFrom(
          padding: EdgeInsets.zero,
          backgroundColor: Theme.of(context).brightness == Brightness.light
              ? AppColor.defaultWhite
              : AppColor.defaultLightBlack,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(20),
          ),
        ),
        child: Icon(
          Icons.close,
          color: Theme.of(context).brightness == Brightness.light
              ? AppColor.defaultBlack
              : AppColor.defaultWhite,
        )
      )
    );
  },
)

通过使用***BlocBuilder***,小部件将为状态的每次发射进行重建,允许并发构建。

相关问题