Flutter Flatter BLoC-StreamSubscription未侦听已调度事件

Flutter Flatter BLoC-StreamSubscription未侦听已调度事件,flutter,bloc,Flutter,Bloc,我正在使用包来管理我的应用程序的状态,但是自从上次包更新(v0.22.1)以来,我有一个奇怪的行为 简单来说,我在EventsBloc中的PositionBloc状态上有一个StreamSubscription侦听器,但当我从PositionBloc添加事件时,侦听器不工作。 最奇怪的是,我第一次从EventsBloc添加事件时,侦听器工作,但之后似乎完全被忽略了 这是我的构建树: main.dart:这里我显示了主页或基于身份验证的登录页面AuthenticationBloc和MoviesBl

我正在使用包来管理我的应用程序的状态,但是自从上次包更新(v0.22.1)以来,我有一个奇怪的行为

简单来说,我在
EventsBloc
中的
PositionBloc
状态上有一个
StreamSubscription
侦听器,但当我从
PositionBloc
添加事件时,侦听器不工作。 最奇怪的是,我第一次从
EventsBloc
添加事件时,侦听器工作,但之后似乎完全被忽略了

这是我的构建树:

main.dart
:这里我显示了主页或基于身份验证的登录页面
AuthenticationBloc
MoviesBloc
不重要,或者
LocalsBloc
重点是
PositionBloc

class App extends StatelessWidget {
  ...
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      builder: (context) => MoviesBloc()..add(LoadMovies()),
      child: MaterialApp(
        home: BlocBuilder<AuthenticationBloc, AuthenticationState>(
          builder: (context, state) {
            if (state is Unauthenticated) {
              return Login(
                authenticationRepository: _authenticationRepository,
              );
            }
            if (state is Authenticated) {
              return MultiBlocProvider(
                providers: [
                  BlocProvider<LocalsBloc>(
                    builder: (context) => LocalsBloc()..add(LoadLocals()),
                  ),
                  BlocProvider<PositionBloc>(
                    builder: (context) => PositionBloc(
                      localsBloc: BlocProvider.of<LocalsBloc>(context),
                    ),
                  )
                ],
                child: Home(),
              );
            }
            return Splash();
          },
        ),
      ),
    );
  }
}
search\u bar.dart
:这是一个用于管理
\u textController
\u focusNode
StatefulWidget
。这里我有我的应用程序状态转换器。我使用package来构建搜索栏,搜索栏的条目来自我们在main.dart中看到的
LocalsBloc
。当我点击一个条目时,我将事件
UpdatePosition
(本地)添加到
PositionBloc

class _SearchBarState extends State<SearchBar> {
  ...
  @override
  Widget build(BuildContext context) {
    return BlocBuilder<PositionBloc, PositionState>(
      builder: (context, state) {
        if (state is PositionUpdated) {
          if (!_focusNode.hasFocus) {
            _textController.text = state.position.local.description;
          }

          return Container(
            decoration: BoxDecoration(
              color: Colors.white,
            ),
            width: MediaQuery.of(context).size.width * 0.75,
            child: TypeAheadField<Local>(
                getImmediateSuggestions: true,
                textFieldConfiguration: TextFieldConfiguration(
                  decoration: InputDecoration(
                    border: OutlineInputBorder(
                      borderRadius: BorderRadius.all(
                        Radius.circular(10.0),
                      ),
                    ),
                    hintText: "Inserisci una posizione",
                    contentPadding: EdgeInsets.all(15),
                  ),
                  focusNode: _focusNode,
                  controller: _textController,
                ),
                suggestionsCallback: (String pattern) {
                  return (BlocProvider.of<LocalsBloc>(context).state as LocalsLoaded)
                      .locals
                      .where(
                        (local) =>
                            local.description
                                .toLowerCase()
                                .contains(pattern.toLowerCase()),
                      )
                      .toList();
                },
                noItemsFoundBuilder: (context) {
                  return Text('Nessun risultato trovato');
                },
                itemBuilder: (context, Local suggestion) {
                  return Card(
                    child: ListTile(
                      title: Text(suggestion.description),
                      subtitle: Text(suggestion.town),
                      trailing: Icon(Icons.gps_not_fixed),
                    ),
                  );
                },
                onSuggestionSelected: (Local suggestionSelected) {
                  BlocProvider.of<PositionBloc>(context).add(
                    UpdatePosition(suggestionSelected),
                  );
                }),
          );
        } else {
          return Container();
        }
      },
    );
  }

此侦听器在第一个widgets树构建后不工作,但当我从搜索栏中选择的条目中添加event UpdatePosition时,PositionBloc的状态将更改,并且事件将正确映射到PositionUpdated。这是一个非常奇怪的情况,可以帮我吗?

我刚刚注意到我错过了对我的
PositionUpdated
状态在CTORs初始值设定项中的一个超级调用,因此没有调用侦听器。这是我的错误,我已经在调试中跟踪了三天

class _SearchBarState extends State<SearchBar> {
  ...
  @override
  Widget build(BuildContext context) {
    return BlocBuilder<PositionBloc, PositionState>(
      builder: (context, state) {
        if (state is PositionUpdated) {
          if (!_focusNode.hasFocus) {
            _textController.text = state.position.local.description;
          }

          return Container(
            decoration: BoxDecoration(
              color: Colors.white,
            ),
            width: MediaQuery.of(context).size.width * 0.75,
            child: TypeAheadField<Local>(
                getImmediateSuggestions: true,
                textFieldConfiguration: TextFieldConfiguration(
                  decoration: InputDecoration(
                    border: OutlineInputBorder(
                      borderRadius: BorderRadius.all(
                        Radius.circular(10.0),
                      ),
                    ),
                    hintText: "Inserisci una posizione",
                    contentPadding: EdgeInsets.all(15),
                  ),
                  focusNode: _focusNode,
                  controller: _textController,
                ),
                suggestionsCallback: (String pattern) {
                  return (BlocProvider.of<LocalsBloc>(context).state as LocalsLoaded)
                      .locals
                      .where(
                        (local) =>
                            local.description
                                .toLowerCase()
                                .contains(pattern.toLowerCase()),
                      )
                      .toList();
                },
                noItemsFoundBuilder: (context) {
                  return Text('Nessun risultato trovato');
                },
                itemBuilder: (context, Local suggestion) {
                  return Card(
                    child: ListTile(
                      title: Text(suggestion.description),
                      subtitle: Text(suggestion.town),
                      trailing: Icon(Icons.gps_not_fixed),
                    ),
                  );
                },
                onSuggestionSelected: (Local suggestionSelected) {
                  BlocProvider.of<PositionBloc>(context).add(
                    UpdatePosition(suggestionSelected),
                  );
                }),
          );
        } else {
          return Container();
        }
      },
    );
  }
EventsBloc({@required PositionBloc positionBloc})
  : assert(PositionBloc != null),
    _positionBloc = positionBloc {
positionSubscription = positionBloc.listen((state) {
  if (state is PositionUpdated) {
    add(LoadEvents(state.local));
  }
});