Flutter - Широкие приложения - PullRequest
1 голос
/ 06 июня 2019

Существует ли правильный способ прослушивания модели потока / области действия с «корневой» страницы или местоположения в приложении 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
);}

Этот вид работает, но на самом деле это не так.Не думаю, что кто-то делал это раньше, кто мог бы предложить лучшее решение?

Я мог бы добавить похожего слушателя на каждую страницу, но опять же это кажется действительно ненужным

Ответы [ 3 ]

0 голосов
/ 19 июня 2019

У меня был похожий вопрос, и кто-то нашел решение для него. Может быть, вам тоже это поможет:

Flutter draw Flushbar для любого BuildContext

0 голосов
/ 19 июня 2019

Может быть, этот пример поможет:

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

Чтобы использовать Обертку глобально в вашем приложении, поместите его поверх дерева виджетов.Вы можете поместить его под виджет MaterialApp в файле main.dart.

0 голосов
/ 06 июня 2019

Я сделал что-то слегка похожее.Хотя вы действительно должны поместить это в statefulwidget, добавьте слушателя в initstate, а не в метод сборки виджетов виджета без состояния.

...