Flutter Bloc - 按钮未触发状态更改

soo*_*oon 0 dart flutter bloc

我有一个main.dart自己的main_bloc.dartmain_event.dart并且main_state.dart

main_event:
- AppStarted
- GoingHome
- GoingTestHome

main_State:
- StateHome
- StateTestHome

main_bloc:
Stream<MainState> mapEventToState(
    MainEvent event,
  ) async* {
    if (event is AppStarted) {
      print('mainbloc: AppStarted');
dispatch(GoingHome());
    }
    if (event is GoingHome) {
      print('mainbloc: GoingHome');
      yield StateHome();
    }
    if (event is TestHome) {
      print('mainbloc: TestHome');
      yield StateTestHome();
    }
...
}
Run Code Online (Sandbox Code Playgroud)

在我的main.dart

class _AppState extends State<App> {
  MainBloc _mainBloc;
  @override
  void initState() {
    super.initState();
    _mainBloc = MainBloc();
    _mainBloc.dispatch(AppStarted());/// <-- 1
  }
...

@override
  Widget build(BuildContext context) {
    return BlocProvider(
        builder: (_) => _mainBloc,
        child: MaterialApp(
          title: 'Home',
          theme: ThemeData(
            ...
          ),
          home: BlocListener<MainBloc, MainState>(
              bloc: _mainBloc,
              listener: (context, state) {
                print('state changed: ${state.toString()}');
                if (state is StateHome) {  /// <-- 2
                  print('main: StateHome');
                  _mainBloc.dispatch(TestHome()); /// <-- 2.1
                } else if (state is StateTestHome) {  /// <-- 3
                  print('main: StateTestHome');
                }
              },
              child: SplashPage()),
...
Run Code Online (Sandbox Code Playgroud)

我做一个快速测试:

  1. 当应用程序启动时,_mainBloc.dispatch(AppStarted())被调用,它将dispatch(GoingHome())main_bloc.
  2. BlocListener 检测到状态变化('StateHome'),所以:

    print('main: StateHome'); _mainBloc.dispatch(TestHome());

  3. BlocListener 再次检测到状态变化('StateTestHome'),所以:

    print('main: StateTestHome');

在控制台中,我可以按顺序看到所有打印消息:

Restarted application in 1,612ms.
I/flutter (15369): mainbloc: AppStarted
I/flutter (15369): mainbloc: GoingHome
I/flutter (15369): state changed: StateHome
I/flutter (15369): main: StateHome
I/flutter (15369): mainbloc: TestHome
I/flutter (15369): state changed: StateTestHome
I/flutter (15369): main: StateTestHome
Run Code Online (Sandbox Code Playgroud)

到目前为止,它以我预期的方式运行。

但是当我取出 code 2.1,然后添加一个按钮来触发事件:

...
floatingActionButton: FloatingActionButton(
        child: Text('test'),
        onPressed: () {
          _mainBloc.dispatch(TestHome());
        },
      ),
...
Run Code Online (Sandbox Code Playgroud)

我会得到这样的控制台:

Restarted application in 2,738ms.
I/flutter (15369): mainbloc: AppStarted
I/flutter (15369): mainbloc: GoingHome
I/flutter (15369): state changed: StateHome
I/flutter (15369): main: StateHome
I/flutter (15369):
I/flutter (15369): mainbloc: TestHome ///<-- button trigger
Run Code Online (Sandbox Code Playgroud)

我预计:

Restarted application in 2,738ms.
I/flutter (15369): mainbloc: AppStarted
I/flutter (15369): mainbloc: GoingHome
I/flutter (15369): state changed: StateHome
I/flutter (15369): main: StateHome
I/flutter (15369):
I/flutter (15369): mainbloc: TestHome ///<-- button trigger
I/flutter (15369): state changed: StateTestHome ///<-- expectation
I/flutter (15369): main: StateTestHome          ///<-- expectation
Run Code Online (Sandbox Code Playgroud)

似乎按钮交互没有yield状态,或者BlocListener没有捕获状态更改事件。

我在这里缺少什么?我该如何解决这个问题?

Ibr*_*han 5

Bloc捕获事件,但您正在尝试发送连续的相同状态。尝试上面的另一个产量yield StateTestHome();

喜欢

yield StateIgnored(); // *****
yield StateTestHome();
Run Code Online (Sandbox Code Playgroud)

编辑:或者您可以删除Equatable抽象。