Flutter-应用范围的通知 [英] Flutter - Application Wide Notifications

查看:70
本文介绍了Flutter-应用范围的通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is there a correct way to listen to a stream / scoped model from a 'root' page or location in a Flutter app and upon receiving some data display an appropriate notification (e.g. Snackbar) on any currently open page (may not be the home page)?

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

I'd like to be able to display certain notifications across the entire application and not just on a page by page basis.

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

Here I have a home page that's my apps initial page, it starts listening to a stream from a scoped_model retrieved from context and whenever data is received displays a dialog regardless of the page the user is visiting.

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
);}

这种作品,但确实感觉不正确-有谁在提供更好的解决方案之前完成了此举?

This kind of works but really doesn't feel correct - has anyone done this before who could offer a better solution?

我可以在每个页面上添加一个类似的侦听器,但再次似乎确实没有必要

I could add a similar listener to every page but again that seems really unnecessary

推荐答案

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

++++ Update July 2019 ++++

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

I wrote a Package that supports application wide message display.

EZ Flutter是小部件,程序包和许多其他有用的东西的集合,它们混合在一个很小的框架中.目的是使标准功能从头开始可用. EZ Flutter支持仅使用一行代码就可以从应用程序内的任何位置向用户显示消息.

EZ Flutter is a collection of widgets, packages and many more usefull things, mixed up in little framework. The aim is to make standard features available from scratch. EZ Flutter supports displaying a message to the user from anywhere inside the app with just one line of code.

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

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

dependencies:
  ez_flutter: ^0.2.0

查看文档,了解如何使用不同的配置.

Check out the documentation how using different configurations works.

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

++++旧答案++++

++++ Old Answer ++++

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

Maybe this example will help :

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

这个想法是要有一个messagewrapper小部件,该小部件显示带有小吃条的消息,这些消息会被推送到BLOC中.

The idea is to have a messagewrapper widget that displays messages with a snackbar that are pushed into a 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);
  }
}

要在您的应用程序中全局使用包装器,请将其放在小部件树的顶部.您可以将其放在main.dart文件中的MaterialApp窗口小部件下.

To use the Wrapper globally in your app, put him on top of the widget tree. You could put it under your MaterialApp Widget in the main.dart file.

这篇关于Flutter-应用范围的通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆