【问题标题】:Flutter draw Flushbar over any BuildContextFlutter 在任何 BuildContext 上绘制 Flushbar
【发布时间】:2019-11-02 00:31:24
【问题描述】:

我使用flushbar 向用户显示应用内通知,但我认为这个问题适用于任何想要覆盖在当前屏幕上的小部件,例如快餐栏。

我希望能够显示独立于屏幕之间导航的通知,即,如果用户在屏幕之间导航,则通知应该保留在所有屏幕上。因为 flushbar 通知仅绘制在当前 BuildContext 上,所以一旦用户关闭当前屏幕,通知也会消失(因为通知小部件是该屏幕小部件子树的一部分)。

有没有办法在整个应用程序的顶部显示一个小部件(例如通知),无论导航如何?

EDIT1:添加了示例代码。

import 'package:flushbar/flushbar_route.dart' as route;
import 'package:flushbar/flushbar.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: FirstScreen(),
    );
  }
}

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Screen'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('go to second screen'),
          onPressed: () {
            Navigator.of(context).push(
              MaterialPageRoute(builder: (BuildContext context) => SecondScreen())
            );
          },
        ),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {

  final Flushbar _flushbar = Flushbar(message: 'Flushbar Notification');

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Screen'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('show flushbar'),
          onPressed: () {
            showFlushbar(_flushbar, context);
          },
        ),
      ),
    );
  }
}

Future showFlushbar(Flushbar instance, BuildContext context) {
  final _route = route.showFlushbar(
    context: context,
    flushbar: instance,
  );

  return Navigator.of(context, rootNavigator: true).push(_route);
}

结果将如下所示(返回第一个屏幕时,我希望通知留在屏幕上):

EDIT2: George 的解决方案有效。此外,使用覆盖也可能是其他人的合适解决方案(请参阅this blog post),即,即使在路线导航期间,覆盖也会保持在屏幕上。但是,在我的情况下,叠加解决方案不太优雅,因为它不允许刷新栏被关闭或动画(或者至少它不那么简单)。

相关问题:Flutter - Application Wide Notifications

【问题讨论】:

    标签: flutter


    【解决方案1】:

    尝试从根导航器显示您的 Flushbar。

    查看flushbar lib的the sources,我们可以通过从package:flushbar/flushbar_route.dart导入showFlushbar方法来创建自己的Flushbar路由。

    例如

    import 'package:flushbar/flushbar_route.dart' as route;
    
    // ...
    
    Future showFlushbar(Flushbar instance) {
      final _route = route.showFlushbar(
        context: context,
        flushbar: instance,
      );
    
      return Navigator.of(context, rootNavigator: true).push(_route);
    }
    

    更新

    感谢您在问题中添加代码。

    在我看来,最终的解决方案是在 MaterialApp 内部创建另一个 Navigator - 某种第二个“子根”导航器。

    现在您可以根据需要在 2 层 Navigator 之间进行选择。

    Navigator.of(context, rootNavigator: true) 将返回顶级导航器 - 将其用于您的 Flushbar 或您希望在所有屏幕上方保持持久的任何其他模式弹出窗口。

    Navigator.of(context),其中rootNavigator 默认为false。使用它来获取“子根”导航器以显示新屏幕/页面。

    例如在MaterialApp 中放置另一个Navigator。

    MaterialApp(
      home: Navigator( // 'sub-root' navigator. Second in the hierarchy.
        onGenerateRoute: (_) => MaterialPageRoute(
          builder: (_) => FirstScreen(),
          settings: RouteSettings(isInitialRoute: true),
        ),
      ),
    );
    

    如果这有帮助,请告诉我。

    【讨论】:

    • 谢谢你的回答,乔治!不幸的是,这对我不起作用。刷新条被推到当前屏幕的顶部,但是一旦当前屏幕(路由)关闭(Navigator.of(context).pop()),它也会关闭刷新条(可能是因为当前屏幕的所有子路由都从导航器中弹出以及)。
    • @chris 请用一些代码扩展您的问题 - 您究竟如何初始化 Flushbar 以及您在何处/何时调用.pop()。
    • 我在我的问题中添加了一些代码,这些代码已经包含您的答案。在这个例子中,我没有明确地调用.pop(),但是当点击appBar上的返回按钮时问题是一样的。
    【解决方案2】:

    这对我有用。

    当我弹出前一个屏幕时,刷新消息将显示在前一个屏幕上。

    onPressed: () {
       Navigator.pop(context);
       Flush.showGoodFlushbar(context, 'login successful!');
    }
    

    【讨论】:

      猜你喜欢
      • 2020-02-29
      • 1970-01-01
      • 2018-08-12
      • 2021-03-13
      • 2020-09-03
      • 1970-01-01
      • 2021-03-16
      • 2023-02-11
      • 2020-10-30
      相关资源
      最近更新 更多