Flutter Bloc - mapEventToState 只执行一次

Flutter Bloc - mapEventToState executes only once

大家好,

我是 Flutter 新手。我正在尝试使用 Bloc 进行简单的状态管理。我有一个主屏幕,其中 show/hides 一些小部件取决于状态。在一个单独的屏幕上,我有两个按钮,它们将事件添加到更新状态的流中,然后主屏幕上的小部件对状态更新做出反应。它工作正常,但 UI 仅在第一个事件之后重建,在后续事件中,集团产生状态,但 UI 不更新。同样在 main.dart Material 中,应用程序使用 MultBlocProvider 包装。我来自南非,所以我可能无法立即回复 bc of timezones 但任何帮助将不胜感激。以下是代码片段。

auth_state.dart

class AuthState {
  bool isLoggedIn = false;
}

auth_event.dart

enum EventType { login, logout }

class AuthEvent {
  late EventType eventType;

  AuthEvent.login() {
    this.eventType = EventType.login;
  }

  AuthEvent.logout() {
    this.eventType = EventType.logout;
  }
}

auth_bloc.dart

class AuthBloc extends Bloc<AuthEvent, AuthState> {
  AuthBloc(AuthState initialState) : super(initialState);

  @override
  Stream<AuthState> mapEventToState(AuthEvent event) async* {
    switch (event.eventType) {
      case EventType.login:
        AuthState newState = state;
        newState.isLoggedIn = true;
        yield newState;
        break;
      case EventType.logout:
        AuthState newState = state;
        newState.isLoggedIn = false;
        yield newState;
        break;
      default:
        throw Exception('Event not found $event');
    }
  }
}

home_page.dart(片段)-> bloc comsumer

 Padding(
   padding: const EdgeInsets.only(right: 30),
   child: BlocConsumer<AuthBloc, AuthState>(
     listener: (context, state) {},
     builder: (context, state) {
       return Visibility(
         visible: state.isLoggedIn,
         child: IconButton(
           key: HomePage.navigateToNotifications,
           onPressed: () {
             Navigator.push(
               context,
               MaterialPageRoute(
                 builder: (context) => Notifications()),
             );
           },
           icon: Icon(Icons.circle_notifications,
             size: 50, color: HexColor('27B88D'))),
       );
     }))

test_page.dart(片段)-> 火团事件

          ElevatedButton(
              onPressed: () =>
                  BlocProvider.of<AuthBloc>(context).add(AuthEvent.login()),
              child: Text('Log User in')),
          ElevatedButton(
              onPressed: () =>
                  BlocProvider.of<AuthBloc>(context).add(AuthEvent.logout()),
              child: Text('Log User out'))

我发现为状态声明单独的状态 类 比同一状态的新实例更容易。

abstract class AuthState {}

class NotLoggedIn extends AuthState {}

class LoggedIn extends AuthState {}

那么你的mapEventToState看起来像这样

  @override
  Stream<AuthState> mapEventToState(AuthEvent event) async* {
    switch (event.eventType) {
      case EventType.login:
        {
          yield LoggedIn();
          break;
        }

      case EventType.logout:
        {
          yield NotLoggedIn();
          break;
        }

      default:
        throw Exception('Event not found $event');
    }
  }

然后你的 BlocConsumer 看起来像这样,它会按照你的预期重建

            Padding(
              padding: const EdgeInsets.only(right: 30),
              child: BlocConsumer<AuthBloc, AuthState>(
                listener: (context, state) {},
                builder: (context, state) {
                  return Visibility(
                    visible: state is LoggedIn ? true : false,
                    child: IconButton(
                        onPressed: () {},
                        icon: Icon(Icons.circle_notifications,
                            size: 50, color: Colors.amber)),
                  );
                },
              ),
            )