繁体   English   中英

Flutter BLoC - StreamSubscription 不监听已调度的事件

[英]Flutter BLoC - StreamSubscription not listen on dispatched event

I'm using the Flutter BLoC package for manage the state of my app, but since last package update (v0.22.1) I have a strange behavior.

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

这是我的构建树:

main.dart :这里我显示主页或基于身份验证的登录页面。 AuthenticationBlocMoviesBloc并不重要,或者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();
          },
        ),
      ),
    );
  }
}

home.dart :这是一个用于管理TabBarViewStatefulWidget ,在这里我为小部件EventsCarousel EventsBloc SearchBar小部件中,我有调度事件的触发器,因此基于选定的 position 重建EventsCarousel

class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
  ...
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: TabBarView(
          children: <Widget>[
            Stack(
              alignment: Alignment.topCenter,
              children: <Widget>[
                BlocProvider<EventsBloc>(
                  builder: (context) => EventsBloc(),
                  child: EventsCarousel(),
                ),
                Positioned(
                  child: SearchBar(),
                ),
              ],
            ),
            MoviesList(),
            Settings(),
          ],
          controller: _tabController,
        ),
      ),
      bottomNavigationBar: Material(
        child: TabBar(
          indicatorColor: Colors.deepOrange,
          tabs: <Tab>[
            Tab(
              icon: Icon(
                FontAwesomeIcons.home
              ),
            ),
            Tab(
              icon: Icon(
                FontAwesomeIcons.bullhorn,
              ),
            ),
            Tab(
              icon: Icon(
                FontAwesomeIcons.cogs,
              ),
            ),
          ],
          controller: _tabController,
        ),
      ),
    );
  }

search_bar.dart :这是一个用于管理_textController_focusNodeStatefulWidget 在这里,我有我的应用程序 state 转换器。 我使用Flutter TypeAhead package 来构建搜索栏,我的搜索栏的条目是从我们在LocalsBloc中看到的 LocalsBloc 提供的。 当我点击一个条目时,我将事件UpdatePosition (local) 添加到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();
        }
      },
    );
  }

我有事件和状态的标准 Bloc 样板,特别是 EventsBloc,因为我说过我有这个订阅:

EventsBloc({@required PositionBloc positionBloc})
  : assert(PositionBloc != null),
    _positionBloc = positionBloc {
positionSubscription = positionBloc.listen((state) {
  if (state is PositionUpdated) {
    add(LoadEvents(state.local));
  }
});

此侦听器在第一个小部件树构建后不起作用,但是当我从搜索栏中的条目选择中添加事件 UpdatePosition 时,PositionBloc 的 state 发生变化,并且事件正确映射到 PositionUpdated。 这是一个很奇怪的情况,能帮帮我吗?

我刚刚注意到我错过了 CTORs 初始化程序中针对我的PositionUpdated state 的超级调用,因此没有调用侦听器。 这是我的错误,我在调试中已经跟踪了三天。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM