Как получить AlertDialog Callback из статического метода во Flutter?

У меня есть AlertDialog в статическом методе, в котором я хочу получить обратный вызов, когда пользователь нажимает на OK кнопка.

Я пытался с помощью typedef но не могу понять.

Ниже мой код:

class DialogUtils{

  static void displayDialogOKCallBack(BuildContext context, String title,
      String message)
  {
    showDialog(
      context: context,
      builder: (BuildContext context) {
         return AlertDialog(
          title: new Text(title, style: normalPrimaryStyle,),
          content: new Text(message),
          actions: <Widget>[
            new FlatButton(
              child: new Text(LocaleUtils.getString(context, "ok"), style: normalPrimaryStyle,),
              onPressed: () {
                Navigator.of(context).pop();
                // HERE I WANTS TO ADD CALLBACK
              },
            ),
          ],
        );
      },
    );
  }
}

3 ответа

Решение

Вы можете просто подождать, пока диалоговое окно будет закрыто {возвращает ноль} или закрыто, нажав OK который в этом случае вернется true

class DialogUtils {
  static Future<bool> displayDialogOKCallBack(
      BuildContext context, String title, String message) async {
    return await showDialog<bool>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: new Text(title, style: normalPrimaryStyle,),
          content:  Text(message),
          actions: <Widget>[
             FlatButton(
              child:  Text(LocaleUtils.getString(context, "ok"), style: normalPrimaryStyle,),
              onPressed: () {
                Navigator.of(context).pop(true);
                // true here means you clicked ok
              },
            ),
          ],
        );
      },
    );
  }
}

А потом когда звонишь displayDialogOKCallBack вам следует await за результат

Пример:

onTap: () async {
  var result =
  await DialogUtils.displayDialogOKCallBack();

  if (result == false) {
   // Ok button is clicked
  }
}

Затем функция обратного вызова для будущей работы:

  DialogUtils.displayDialogOKCallBack().then((value) {
  if (value) {
   // Do stuff here when ok button is pressed and dialog is dismissed. 
  }
});

Этот поток немного устарел, но я нашел решение, которое не было затронуто, поэтому я решил добавить его сюда.

У меня была форма в моем AlertDialog, и мне нужно было держать диалог открытым, если были какие-либо ошибки. Это решение сработало для меня.

      final GlobalKey<FormState> formKey = GlobalKey<FormState>();

Future _showEditDialog(BuildContext context) {
  return showDialog(
    context: context,
    builder: (context) {
      return WillPopScope(
        onWillPop: () async {
          return formKey.currentState!.validate();
        },
        child: AlertDialog(
          title: const Text("Awesome AlertDialog"),
          content: SingleChildScrollView(
            physics: const BouncingScrollPhysics(),
            child: Form(
              key: formKey,
              child: Column(
                children: [
                  TextFormField(
                    validator: (value) {
                      if (value!.isEmpty) return "Please Fill Out This Field";
                      return null;
                    },
                  ),
                ],
              ),
            ),
          ),
          actions: <Widget>[
            MaterialButton(
              child: const Text("Cancel"),
              onPressed: () {
                Navigator.pop(context);
              },
            ),
          ],
        ),
      );
    },
  );
}

Важная часть — это WillPopScope, в который я обернул AlertDialog. Я думаю, что это поглощает все вызовы Navigator.pop() и передает их через параметр onWillPop. Этот параметр передается асинхронной функции, которая возвращает Future. Я только что вернул логическое значение проверки проверки, но в реальном мире здесь также будет HTTP-запрос.

Не забудьте добавить способ для пользователя отменить форму, не запуская проверку формы. Я только что добавил кнопку отмены, которая запускает Navigator.pop().

Надеюсь, это поможет, дайте мне знать, если у кого-то есть какие-либо вопросы.

Другие вопросы по тегам