[英]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.
简单来说,我在StreamSubscription
的PositionBloc
的EventsBloc
上有一个 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();
},
),
),
);
}
}
home.dart
:这是一个用于管理TabBarView
的StatefulWidget
,在这里我为小部件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
和_focusNode
的StatefulWidget
。 在这里,我有我的应用程序 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.