Flutter 中没有上下文的 AlertDialog

Fra*_*ano 24 dialog dart flutter

我想在 http 获取失败时显示 AlertDialog。函数 showDialog ( https://api.flutter.dev/flutter/material/showDialog.html ) 有参数“@required BuildContext context”,但我想从我的异步函数 getNews() 调用 AlertDialog,它没有t 上下文值。

与 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),
        ...
    );
  }
Run Code Online (Sandbox Code Playgroud)

Igo*_*din 54

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

final navigatorKey = GlobalKey<NavigatorState>();

void main() => runApp(
  MaterialApp(
    home: HomePage(),
    navigatorKey: navigatorKey, // Setting a global key for navigator
  ),
);

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: SafeArea(
        child: Center(
          child: Text('test')
        )
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: showMyDialog, // Calling the function without providing it BuildContext
      ),
    );
  }
}

void showMyDialog() {
  showDialog(
    context: navigatorKey.currentContext,
    builder: (context) => Center(
      child: Material(
        color: Colors.transparent,
        child: Text('Hello'),
      ),
    )
  );
}
Run Code Online (Sandbox Code Playgroud)

为 navigator (类的navigatorKey参数MaterialApp)设置全局键后,它的当前状态可以从代码的任何部分访问。我们可以将其上下文传递给showDialog函数。确保在第一帧构建之前不要使用它,否则状态将为空。

基本上,对话框只是另一种类型的路由,例如MaterialPageRouteor CupertinoPageRoute- 它们都派生自ModalRoute该类,并且它们的实例被推入NavigatorState. 上下文只需要获取当前导航器的状态。如果我们有全局导航键,则可以在没有上下文的情况下推送新路由:

navigatorKey.currentState.push(route)
Run Code Online (Sandbox Code Playgroud)

不幸的是,函数中_DialogRoute使用的类 (...\flutter\lib\src\widgets\routes.dart)showDialog是私有的并且无法访问,但是您可以创建自己的对话框路由类并将其推送到导航器的堆栈中。

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

  • 如果您确定您的 navigatorKey 在您想要显示对话框时已经有了上下文,请强制解开您的 currentContext 变量,如下所示“context: navigatorKey.currentContext!” (2认同)

jon*_*ges 6

接受的答案是错误的。

对话框只需要上下文就可以通过继承的navigateState 访问它。您可以制作自己的修改对话框,或使用我的库来执行此操作。

https://pub.dev/packages/get

有了它,您可以通过执行以下操作从代码中的任何位置打开对话框,而无需上下文:

Get.dialog(SimpleDialog());
Run Code Online (Sandbox Code Playgroud)

  • 如果不需要,请勿强制使用第 3 方库。使用“final navigatorKey = GlobalKey&lt;NavigatorState&gt;();”查看答案 (3认同)