Flutter Cubit,听听其他 Cubit 状态

Flutter Cubit, Listen to other Cubit states

我尝试实现一个 FilterEventCubit 来监听 LocationTrackerCubit 和 EventLoaderCubit 的状态。我使用了 Felix Angelov (https://bloclibrary.dev/#/fluttertodostutorial) 的教程作为模板:

class EventFilterCubit extends Cubit<EventFilterState> {
  final EventLoaderCubit eventLoaderCubit;
  final UserCubit userCubit;
  final LocationTrackerCubit locationTrackerCubit;
  StreamSubscription? eventsSubscription;
  StreamSubscription? locationSubscription;

  EventFilterCubit(
      this.eventLoaderCubit, this.userCubit, this.locationTrackerCubit)
      : super(
          eventLoaderCubit.state is EventsUpToDate &&
                  userCubit.state is UserUpToDate &&
                  // TODO: not working correctly
                  locationTrackerCubit.state is LocationLoadSuccess
              ? EventFilterState.filteredEventsLoadSuccess(
                  (eventLoaderCubit.state as EventsUpToDate).events,
                  EventFilter.initial(
                    LatLng(
                      (locationTrackerCubit.state as LocationLoadSuccess)
                          .location
                          .latitude,
                      (locationTrackerCubit.state as LocationLoadSuccess)
                          .location
                          .longitude,
                    ),
                  ),
                )
              : const EventFilterState.filteredEventsLoadInProgress(),
        ) {
    eventsSubscription = eventLoaderCubit.stream.listen(
      (state) {
        if (state is EventsUpToDate) {
          print("Eventloaderbloc updated events");
          eventsUpdated((eventLoaderCubit.state as EventsUpToDate).events);
        }
      },
    );
    locationSubscription = locationTrackerCubit.stream.listen(
      (state) {
        if (state is LocationLoadSuccess) {
          print("locationtrackercubit updated location");
          locationUpdated(
            (locationTrackerCubit.state as LocationLoadSuccess).location,
          );
        }
      },
    );
  }

EventFilterCubit 然后构建包含所有事件的提要。 当我构建应用程序或进行热重启时,一切正常。但它在第一次状态更新后停止监听,因此无论何时添加新事件或重新加载事件,UI 中都不会发生任何事情,并且不会触发 updateEvents 函数。 这也是我的 EventLoaderCubit:

part 'event_loader_cubit.freezed.dart';
part 'event_loader_state.dart';

@injectable
class EventLoaderCubit extends Cubit<EventLoaderState> {
  final IEventRepository eventRepository;

  // TODO: Streams atm useless
  final StreamController<List<Event>> _eventController =
      StreamController<List<Event>>();
  Stream<List<Event>> get eventStream => _eventController.stream;

  EventLoaderCubit(this.eventRepository)
      : super(
          const EventLoaderState.loadInProgress(),
        ) {
    refreshEvents();
  }

  Future<void> refreshEvents() async {
    print("refresh events");
    emit(const EventLoaderState.loadInProgress());
    final eventsFailOrSuccess = await eventRepository.loadEvents();
    eventsFailOrSuccess.fold(
      (failure) => emit(
        const EventLoaderState.loadFailure(
          EventFailure.serverError(),
        ),
      ),
      (events) {
        _eventController.add(events);
        // getIt<EventFilterCubit>().eventsUpdated(events);
        emit(
          EventLoaderState.eventsUpToDate(events),
        );
      },
    );
  }
}

以及提供程序初始化:

child: BlocProvider(
        create: (context) => getIt<AuthCubit>()..initialized(),
        child: BlocBuilder<AuthCubit, AuthState>(
          builder: (context, state) {
            if (state is Authenticated) {
              return MultiBlocProvider(
                providers: [
                  BlocProvider<LocationTrackerCubit>(
                    create: (context) => getIt<LocationTrackerCubit>(),
                  ),
                  BlocProvider<UserCubit>(
                    create: (context) => getIt<UserCubit>(),
                  ),
                  BlocProvider<EventLoaderCubit>(
                    create: (context) =>
                        // TODO: Doesn't execute refreshEvents()
                        getIt<EventLoaderCubit>(),
                  ),
                  BlocProvider<EventFilterCubit>(
                    create: (context) => getIt<EventFilterCubit>(),
                  ),
                ],
                child: _materialApp(context, authedRouter),

此外,正如代码中所写,refreshEvents() 函数在注入 Cubit 时不会运行。

我在 getIt 依赖注入和 BloC 方面也遇到了麻烦。我通过更改对 context.read 的 bloc 访问权限解决了这个问题,现在它工作正常。

您可以尝试类似的方法:

return MultiBlocProvider(
  providers: [
    BlocProvider<UserCubit>(
      lazy: false,
      create: (context) => UserCubit(
        getIt<IUserRepository>(),
      ),
    ),
    BlocProvider<LocationTrackerCubit>(
      lazy: false,
      create: (context) => LocationTrackerCubit(),
    ),
    BlocProvider<EventLoaderCubit>(
      lazy: false,
      create: (context) => EventLoaderCubit(
        getIt<IEventRepository>(),
      ),
    ),
    BlocProvider<EventFilterCubit>(
      create: (context) => EventFilterCubit(
        eventLoaderCubit:
            BlocProvider.of<EventLoaderCubit>(context),
        userCubit: BlocProvider.of<UserCubit>(context),
        locationTrackerCubit:
            BlocProvider.of<LocationTrackerCubit>(context),
      ),
    ),
  ],