我有以下bloc提供商
class CloudMessagingBloc{
StreamController<NotificationModel> _streamController = StreamController<NotificationModel>();
Stream<NotificationModel> get stream => _streamController.stream;
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
CloudMessagingBloc() {
if (Platform.isIOS) _firebaseMessaging.requestNotificationPermissions(IosNotificationSettings());
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
_streamController.add(NotificationModel.fromMap(message));
},
onLaunch: (Map<String, dynamic> message) async {
_streamController.add(NotificationModel.fromMap(message));
},
onResume: (Map<String, dynamic> message) async {
_streamController.add(NotificationModel.fromMap(message));
},
);
}
void dispose(){
_streamController.close();
}
}
并像这样实现它
static Widget create() {
return MultiProvider(
providers: [
Provider(create: (_) => DelayBloc(seconds: 2)),
Provider(
create: (_) => CloudMessagingBloc(),
dispose: (BuildContext context, CloudMessagingBloc bloc) => bloc.dispose(),
lazy: false,
),
],
child: TheRootPage(),
);
}
在我的根页面无状态小部件中。但是现在我有一个问题,因为每当流发出新值时,我都希望显示一次对话框。因此,我为此强加了一个streambuilder,并且在添加新值时通知会正确显示
StreamBuilder(
stream: cloudMessagingBloc.stream,
builder: (BuildContext context, AsyncSnapshot<NotificationModel> snapshot) {
if (snapshot.connectionState == ConnectionState.active && snapshot.hasData)
SchedulerBinding.instance
.addPostFrameCallback((_) => _showNotificationDialog(context, snapshot.data));
但是问题在于,只要重建包含此streambuilder的窗口小部件,由于满足条件(因为我只想要显示一次通知),所以再次显示通知,因为这不是我想要的。那么如何防止这种情况发生呢?感觉像我有一个结构性问题,只是无法解决。
答案 0 :(得分:1)
我看到3种可能的解决方案:
您需要使用https://pub.dev/packages/equatable来检查它是否为新状态。这也来自ferangel(BLOC软件包的作者)。您可以在Google中找到带有Equitable和Bloc的示例。
您可以创建一个全局键,然后使用它来显示对话框(如果您具有全局键,则可以从中检索上下文,然后从bloc中调用dialogService.showMyDialog())。
< / li>例如,您可以使用https://pub.dev/packages/get包从您的集团显示对话框/进行导航,而无需通知Page有关新状态。
我个人更喜欢2或3。 但有时也使用第一个。