Flutter Bloc 没有重建状态

Flutter Bloc is not rebuilding state

我已经使用 flutter_bloc 包实现了这个简单的 bloc:

class MainBloc extends Bloc<MainEvent, MainState> {
  @override
  MainState get initialState => Init();

  @override
  Stream<MainState> mapEventToState(MainEvent event) async* {
    if (event is Event) {
      yield* _mapEventToState();
    }
  }

  Stream<MainState> _mapEventToState() async* {
    final loadState = Load();
    print("Yield state: $loadState");
    yield loadState;
    await sleep(Duration(seconds: 1));
    final initState = Init();
    print("Yield state: $initState");
    yield initState;
  }
}

此事件:

abstract class MainEvent {}

class Event extends MainEvent {}

这个状态:

abstract class MainState {}

class Load extends MainState {}

class Init extends MainState {}

我的 UI 看起来像这样:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Material App',
      home: BlocProvider(
        create: (context) => MainBloc(),
        child: Scaffold(
          appBar: AppBar(),
          body: BlocBuilder<MainBloc, MainState>(
            builder: (context, state) {
              print("Build state: $state");
              if (state is Init) {
                return MaterialButton(
                  onPressed: () => BlocProvider.of<MainBloc>(context).add(Event()),
                  child: Text("Press"),
                );
              } else {
                return Text("Loading");
              }
            },
          ),
        ),
      ),
    );
  }
}

不幸的是,如果我使用 MaterialButton 添加我的事件,Load() 状态将被忽略。 UI 不会重建加载状态。输出如下:

I/flutter(1955 年):屈服状态:'Load'

的实例

I/flutter(1955 年):屈服状态:'Init'

的实例

I/flutter(1955 年):构建状态:'Init'

的实例

因为你用的是await sleep(Duration(seconds: 1));await语句在这里没有用,是同步函数)

sleep 函数会暂停主线程的执行,这意味着它还会阻止重建应用程序的主页,因此它没有机会重建,因为新的Load 状态。冻结应用程序结束后,它会立即进入新状态,这就是为什么您永远不会看到加载页面的原因。

改用 await Future.delayed(Duration(seconds: 1));,这会暂停 _mapEventToState 函数其余部分的执行,但不会阻塞主线程,因此您的 MainPage 会得到重建。