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

Android 如何在没有上下文的情况下在应用程序中的任何位置显示对话框?,android,flutter,dart,Android,Flutter,Dart,大家好,这是我问自己很久的问题。我也看到了一些答案,但它并没有解决我的问题,我发现一些类似的问题是:或者 我试图实现的是,在我的应用程序中的任何地方(因此在我的应用程序的任何页面中)显示来自同一段代码的弹出对话框(所以它都是集中的)。问题是,从这段代码中,我无法访问BuildContext,这是因为我显示的弹出窗口基于的事件不是来自用户操作(如按钮点击),而是Firestore侦听器,或者代码深处发生的错误(因此我可以向用户显示错误消息),由于我对代码的了解非常深入,通常我无法访问BuildCo

大家好,这是我问自己很久的问题。我也看到了一些答案,但它并没有解决我的问题,我发现一些类似的问题是:或者

我试图实现的是,在我的应用程序中的任何地方(因此在我的应用程序的任何页面中)显示来自同一段代码的弹出对话框(所以它都是集中的)。问题是,从这段代码中,我无法访问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(),
      );
  }
}
void main()异步{
//在这里,我创建了navigatorKey
GlobalKey navigatorKey=GlobalKey();
//然后我用navigatorKey初始化我的单身
wait repository.init(navigatorKey:navigatorKey);
//然后我将导航工作向下传递到我的应用程序
runApp(MyApp(调试模式:调试模式,导航工作:导航工作));
}
类MyApp扩展了StatefulWidget{
最终航行工作;
const MyApp({Key,this.navigatorKey})
:super(key:key);
@凌驾
MyAppState createState()=>MyAppState();
}
类MyAppState使用WidgetsBindingObserver扩展状态{
@凌驾
小部件构建(构建上下文){
返回材料PP(
navigatorKey:widget.navigatorKey,
标题:“我的应用程序”,
主页:SplashPage(),
主题:_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),
      );
    });
  }
}
类存储库{
GlobalKey get navigatorKey=>\u navigatorKey;
环球航空公司;
void init({GlobalKey navigatorKey}){
_navigatorKey=navigatorKey;
}
void _listenToEvents(){
streamWithEvents.listen((事件){
显示对话框(
上下文:navigatorKey.currentContext,
生成器:()=>CustomMessageDialog(消息:event.message),
);
});
}
}

使用
navigatorKey.currentState.overlay.context
查看对话框的上下文。

非常感谢您的回答!我试试这个,然后再打给你。如果这有效,我会把这个答案作为正确答案。