Flutter - 应用范围的通知

Posted

技术标签:

【中文标题】Flutter - 应用范围的通知【英文标题】:Flutter - Application Wide Notifications 【发布时间】:2019-10-22 03:03:22 【问题描述】:

是否有正确的方法从“根”页面或 Flutter 应用程序中的位置监听流/范围模型,并在接收到一些数据后在任何当前打开的页面上显示适当的通知(例如 Snackbar)(可能不是主页)?

我希望能够在整个应用程序中显示某些通知,而不仅仅是逐页显示。

这里有一个主页,它是我的应用程序初始页面,它开始侦听从上下文中检索到的 scoped_model 的流,并且无论用户正在访问哪个页面,只要接收到数据就会显示一个对话框。

class Home extends StatelessWidget 
@override
Widget build(BuildContext context) 

MyService service  = ScopedModel.of<MyService>(context);

service.events.stream.listen((data) 
  showDialog<String>(
      context: context,
      barrierDismissible: true, // dialog is dismissible with a tap on the barrier
      builder: (BuildContext context) 
        return AlertDialog(
            title: Text('An Event has Occurred'),
            content: Text('$data')););
);

return Scaffold(
//Navigator Push Routes - Page 1 / Page 2 / Page 3 / etc
);

这种方法可行,但感觉不正确 - 有没有人这样做过,谁能提供更好的解决方案?

我可以为每个页面添加一个类似的监听器,但这似乎真的没有必要

【问题讨论】:

我有一个类似的问题,有人找到了解决方案。也许它也对你有帮助:***.com/q/56664760/6586631 【参考方案1】:

我做过类似的事情。尽管您确实应该将它放在有状态的小部件中,但在 initstate 中添加侦听器,而不是在无状态小部件的小部件构建方法中。

【讨论】:

这是一个很好的观点,并且可以防止在每次构建时重置侦听器 - 这是支持应用程序范围通知的最佳方式还是有其他方法可以做到这一点? 你正在做的事情会非常好(有提到的修改)。现在可能不是担心“最佳”做事方式的时候。【参考方案2】:

++++ 2019 年 7 月更新 ++++

我写了一个支持应用程序范围消息显示的包。

EZ Flutter 是小部件、包和许多有用的东西的集合,混合在一个小框架中。目的是从头开始提供标准功能。 EZ Flutter 支持通过一行代码从应用内的任何位置向用户显示消息。

Github:https://github.com/Ephenodrom/EZ-Flutter

dependencies:
  ez_flutter: ^0.2.0

查看文档如何使用不同的配置。

https://github.com/Ephenodrom/EZ-Flutter/blob/master/documentation/GLOBAL_MESSAGE.md

++++ 旧答案 ++++

也许这个例子会有所帮助:

https://github.com/Ephenodrom/Flutter-Advanced-Examples/tree/master/lib/examples/globalMessage

我们的想法是有一个消息包装器小部件,它显示带有推送到 BLOC 中的快餐栏的消息。

class GlobalMessageWrapper extends StatefulWidget 
  final Widget child;

  GlobalMessageWrapper(this.child);
  @override
  _GlobalMessageWrapperState createState() => _GlobalMessageWrapperState();


class _GlobalMessageWrapperState extends State<GlobalMessageWrapper> 
  @override
  Widget build(BuildContext context) 
    return StreamBuilder(
        initialData: null,
        stream: BlocProvider.of<GlobalBloc>(context).messageBloc.messageStream,
        builder: (BuildContext context, AsyncSnapshot<Message> snapshot) 
          Message msg = snapshot.data;
          if (msg != null) 
            WidgetsBinding.instance
                .addPostFrameCallback((_) => _showMessage(msg));
          
          return Container(child: widget.child);
        );
  

  void _showMessage(Message message) 
    Color color = Colors.grey;

    switch (message.type) 
      case "success":
        color = Colors.green;
        break;
      case "info":
        color = Colors.blue;
        break;
      case "warning":
        color = Colors.orange;
        break;
      case "error":
        color = Colors.red;
        break;
      default:
    
    SnackBar bar = SnackBar(
        content: Padding(
          padding: const EdgeInsets.only(bottom: 50.0),
          child: Text(message.text),
        ),
        backgroundColor: color);

    Scaffold.of(context)
      ..hideCurrentSnackBar()
      ..showSnackBar(bar);
  

要在您的应用中全局使用 Wrapper,请将其放在小部件树的顶部。您可以将它放在 main.dart 文件中的 MaterialApp Widget 下。

【讨论】:

以上是关于Flutter - 应用范围的通知的主要内容,如果未能解决你的问题,请参考以下文章

由 GPS 位置触发的 Flutter 本地通知

如何在应用内更改通知声音(Flutter)

Flutter:即使应用关闭也会推送通知

Flutter 双重通知

Flutter 实时通知

Flutter - 如何为消息应用程序实现通知?