android - 如何在没有上下文的情况下在应用程序的任何位置显示对话框?

标签 android flutter dart

大家好,这是我一直在问自己的一个问题。我也看到了一些答案,但它并没有解决我的问题,我发现的一些类似问题是:Flutter showDialog with navigator key rather than passing contextNavigator operation requested with a context that does not include a Navigator

我想要实现的是在我的应用程序的任何地方(所以在我的应用程序的任何页面)中从同一段代码显示弹出对话框(所以它都是集中的)。问题是从那段代码中我无权访问 BuildContext,这是因为我根据不是来自用户操作(如按钮点击)的事件显示此弹出窗口,而不是它们可能是 Firestore 监听器,或者在我的代码深处发生的错误(这样我可以向用户显示错误消息),因为我对代码如此深入,通常我无权访问 BuildContext。

在类似的问题中,我发现了一些看起来像解决方案的东西。这些解决方案使用 GlobalKey 作为导航器,因此可以从任何地方访问它,关于如何在应用程序中的任何地方访问它有一些不同的选项,在我的情况下,我选择了存储这个 globalKey 的 Singleton(我的“存储库”)。然后当事件被触发时,我使用 globalKey 来获取上下文并显示一个对话框,但它会抛出这个错误:

Navigator operation requested with a context that does not include a Navigator.
The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.

@Hemanth Raj 提到您的根小部件需要是 MaterialApp,我确实有一个 MaterialApp 作为我的根。

这是我拥有的应用程序结构的近似值:
void main() async {

  // Here I create the navigatorKey
  GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

  // I then init my Singleton with the navigatorKey
  await repository.init(navigatorKey: navigatorKey);

  // Then I pass the navigatorKey down to my App
  runApp(MyApp(debugMode: debugMode, navigatorKey: navigatorKey));
}

class MyApp extends StatefulWidget {
  final navigatorKey;

  const MyApp({Key key, this.navigatorKey})
      : super(key: key);

  @override
  MyAppState createState() => MyAppState();
}

class MyAppState extends State<MyApp> with WidgetsBindingObserver {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        navigatorKey: widget.navigatorKey,
        title: 'My app',
        home: SplashPage(),
        theme: _buildMyTheme(),
      );
  }
}

然后在我的存储库中,我有一个 firestore 事件的监听器。这些可以在我进入主屏幕后随时触发。这个想法是我在应用程序中找到自己的任何地方,如果触发事件,则应该出现弹出窗口。
class Repository {

  GlobalKey<NavigatorState> get navigatorKey => _navigatorKey;
  GlobalKey<NavigatorState> _navigatorKey;

  void init({GlobalKey<NavigatorState> navigatorKey}) {
    _navigatorKey = navigatorKey;
  }

  void _listenToEvents() {
    streamWithEvents.listen((event) {
      showDialog(
        context: navigatorKey.currentContext,
        builder: (_) => CustomMessageDialog(message: event.message),
      );
    });
  }
}

最佳答案

使用navigatorKey.currentState.overlay.context对于 showDialog的语境。

关于android - 如何在没有上下文的情况下在应用程序的任何位置显示对话框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59787163/

相关文章:

flutter - Flutter 可以在 kiosk 模式下制作应用程序吗?

dart - 奇怪的异步行为

android - Google Maps API v2 在 MapFragment 上绘制部分圆圈

android - 互联网是否需要身份验证才能实际连接才能下载?

java - Android Firebase : invalid case sensitive name

javascript - 如何在 webView 中启用 javascript

json - 如何在 Flutter 中将响应 JSON 转换为对象?

firebase - Stream <QuerySnapshot>返回空文档

dart - 如何简化Dart中的空检查

dart - 如何在 flutter/dart 中替换 $ 符号