Dart 颤振中无上下文的AlertDialog

Dart 颤振中无上下文的AlertDialog,dart,flutter,dialog,Dart,Flutter,Dialog,我想在http get失败时显示AlertDialog。函数showDialog()具有参数“@required BuildContext context”,但我想从异步函数getNews()调用AlertDialog,该函数没有上下文值 与Java类似,我在对话框中使用null,没有所有者,我尝试将上下文值设置为null,但不被接受 这是我的代码: Future<dynamic> getNews() async { dynamic retVal; try {

我想在http get失败时显示AlertDialog。函数showDialog()具有参数“@required BuildContext context”,但我想从异步函数getNews()调用AlertDialog,该函数没有上下文值

与Java类似,我在对话框中使用null,没有所有者,我尝试将上下文值设置为null,但不被接受

这是我的代码:

  Future<dynamic> getNews() async {
    dynamic retVal;
    try {
      var response = await http.get(url));
      if (response.statusCode == HttpStatus.ok) {
        retVal = jsonDecode(response.body);
      }
    } catch (e) {
      alertDlg(?????????, 'Error', e.toString());
  }
    return
    retVal;
  }

  static Future<void> alertDlg(context, String titolo, String messaggio) async {
    return showDialog<void>(
        context: context,
        barrierDismissible: false, // user must tap button!
        builder: (BuildContext context) {
        return AlertDialog(
              title: Text(titolo),
        ...
    );
  }
Future getNews()异步{
动态检索;
试一试{
var response=wait http.get(url));
if(response.statusCode==HttpStatus.ok){
retVal=jsonDecode(response.body);
}
}捕获(e){
alertDlg(???,'Error',例如toString());
}
返回
复述;
}
静态未来警报DLG(上下文、字符串标题、字符串消息)异步{
返回显示对话框(
上下文:上下文,
barrierDismissible:false,//用户必须点击按钮!
生成器:(BuildContext上下文){
返回警报对话框(
标题:文本(titolo),
...
);
}

捕获异常,如果使用wait,则调用getNews,否则使用未来的catchError属性。

因此,您需要一个
构建上下文来创建对话框,但您无权访问它。这是一个常见问题,您可以参考其中一种解决方法(创建一个静态对话框,并在需要的地方显示它)

你可以考虑的另一个方法是在创建一个异步方法或对象作为参数时传递上下文。


或者,您可以设置一个在特定条件下变为“真”的标志(布尔值),并且在一个
build()
方法中,您总是检查该标志,如果该标志为“真”,则执行您的操作(例如显示一个对话框)。

接受的答案是错误的

对话框只需要上下文就可以通过继承的属性访问它。 您可以创建自己的修改对话框,或使用此库来完成此操作

使用它,您可以在代码中的任何位置打开对话框,无需上下文,方法如下:

Get.dialog(SimpleDialog());

没有第三方库或存储
BuildContext
的解决方案:

final navigatorKey=GlobalKey();
void main()=>runApp(
材料聚丙烯(
主页:主页(),
navigatorKey:navigatorKey,//为navigator设置全局键
),
);
类主页扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(),
正文:安全区(
儿童:中心(
子项:文本('test')
)
),
浮动操作按钮:浮动操作按钮(
onPressed:showMyDialog,//在不提供BuildContext的情况下调用函数
),
);
}
}
void showMyDialog(){
显示对话框(
上下文:navigatorKey.currentContext,
生成器:(上下文)=>中心(
儿童:材料(
颜色:颜色。透明,
child:Text('Hello'),
),
)
);
}
为导航器设置全局键(
MaterialApp
类的
navigatorKey
参数)后,可以从代码的任何部分访问其当前状态。我们可以将其上下文传递到
showDialog
函数。请确保在生成第一帧之前不要使用它,否则状态将为空

基本上,对话框只是另一种类型的路由,如
MaterialPageRoute
CupertinoPageRoute
——它们都是从
ModalRoute
类派生的,它们的实例被推送到
NavigatorState
中。只需要获取当前导航器的状态就可以使用上下文。推送新路由时不需要ha如果我们有一个全局导航键,则选择一个上下文:

navigatorKey.currentState.push(路由)
不幸的是,
\u DialogRoute
函数中使用的类(…\flatter\lib\src\widgets\routes.dart)是私有且不可访问的,但是您创建了自己的DialogRoute类并将其推到导航器堆栈中


UPDATE
Navigator.of
方法已更新,不再需要传递子树上下文。

StatefulWidget
传递您的
Build
上下文,您将在其中显示对
getNews()的http响应
函数。你能举个例子吗。我试着将上下文传递给我的新小部件。它没有给出任何错误,但也没有显示任何警报绕过null没有得到任何编译时错误,但得到相同的失败断言:line'context!=null':不是真的。太棒了。
.overlay
挽救了我的一天!(我发现如果直接使用
navigatorKey.currentState.context
,它将不起作用,因为showDialog需要导航器上下文下方的上下文。)这应该被标记为最佳答案。你真的救了我一天!使用
NavigationWorkery.currentContext
怎么样?它似乎可以工作,但我不确定与
currentState.overlay.context
相比是否存在潜在问题?未处理的异常:NoSuchMethodError:在null.E/flatter(30999)上调用了getter'overlay':Receiver:null E/flatter(30999):尝试调用:overlayUnhandled异常:NoSuchMethodError:getter“overlay”在null上被调用。getting Error这是不可能的。您可能忘记了将“Get”添加到MaterialApp中。将其更改为GetMaterialApp,所有操作都将正常进行。如下面的GetMaterialApp.dialog(SimpleDialog());我尝试了此GetMaterialApp(标题:UtilString.submit);获取编译时错误。否,在主文件上,如果不需要,请不要强制使用第三方库。请使用
final navigatorKey=GlobalKey();