1

我已经出现了一个对话框,如果有人正确输入了某个单词,可以关闭该对话框。我想知道如果有人在某个时间范围内没有在第一个文本框中输入任何内容,是否可以显示第二个对话框。例如,如果该人在接下来的 5 分钟内没有输入文本,有没有办法触发第二个对话框出现?

      Future.delayed(Duration(seconds: 5), () {
        showDialog(
            context: context,
            barrierDismissible: false,
            builder: (context) {
              return AlertDialog(
                title: Text('Your time finished'),
                content: Text('Type "OKAY" if you want to go back to the homepage'),
                actions: <Widget>[
                  TextButton(
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                      child: TextFormField(
                        controller: _textEditingController,
                        validator: (String? word){
                          if (word != OKAY){
                            _NoDialog();
                          }
                          else{
                            Navigator.pop(context);
                          }
                        },
                      ),
                  ),
                ],
              );
            });
      });

如果此人提供的文本不正确,我会调用该函数NoDialog,但如果此人在一段时间内没有在文本框中输入任何内容,我不确定如何做出“if”语句。我认为如果该人将文本留空,然后调用附加了 Future.delayed 的新函数,我可以做一个“if”语句,但是我找不到一种方法来为没有文本的情况下一个“if”语句是进入。同样在这种情况下,我相信该人必须按“输入”键,但我希望显示第二个对话框,因为用户没有触摸屏幕上的任何内容。这可能吗?

4

1 回答 1

0

在简单的情况下,您可以显示嵌套重叠对话框并传递相同的构建上下文。

第一个对话框将是

_userInputCheckerDialog({
    required BuildContext context,
    required String correctText,
    Duration maxTime = const Duration(seconds: 2),
  }) async {
    bool _noInteraction = true;

    /// apear if user doesnt type anything within
    Future.delayed(maxTime).then((t) async {
      if (_noInteraction) await _showSecondDialog(context);
    });
    await showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) {
        return StatefulBuilder(
          ///may need in future to change variable inside dialog
          builder: (context, setStateSB) {
            return AlertDialog(
              content: TextField(
                onChanged: (value) async {
                  _noInteraction = false;
                  if (value == correctText) {
                    Navigator.of(context)
                        .pop(); // close after getting currect text
                  }
                },
              ),
            );
          },
        );
      },
    );
  }

然后内部对话框具有相同的上下文

  _showSecondDialog(BuildContext context) async {
    await showDialog(
      context: context,
      builder: (context) => const AlertDialog(
        content: Text("Hey start typing"),
      ),
    );
  }

这只是检查用户交互的第一次。

如果你想使用 timeframe,我们需要使用 async 包来取消(不是真的取消)未来。你可能会觉得它比第一个复杂一点。

使用异步


  _showSecondDialog(BuildContext context) async {
    await showDialog(
      context: context,
      builder: (context) => const AlertDialog(
        content: Text("Hey start typing"),
      ),
    );
  }

  CancelableOperation _restartTimer({
    CancelableOperation? cancelableOperation,
    Duration duration = const Duration(seconds: 4),
    required BuildContext context,
  }) {
    if (cancelableOperation != null) {
      cancelableOperation.cancel();
      cancelableOperation = null;
    }
    cancelableOperation = CancelableOperation.fromFuture(
      Future.delayed(
        duration,
      ),
    ).then((p0) async {
      await _showSecondDialog(context);
    });

    return cancelableOperation;
  }

  _userInputCheckerDialog({
    required BuildContext context,
    required String correctText,
    Duration maxTime = const Duration(seconds: 2),
  }) async {
    CancelableOperation? _cancelableOperation;

    ///start timer at startUp
    _cancelableOperation = _restartTimer(
      context: context,
      cancelableOperation: _cancelableOperation,
      duration: maxTime,
    );

    await showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) {
        return StatefulBuilder(
          ///may need in future to change variable inside dialog
          builder: (context, setStateSB) {
            return AlertDialog(
              content: TextField(
                onChanged: (value) async {
                  _cancelableOperation = _restartTimer(
                      context: context,
                      cancelableOperation: _cancelableOperation);
                  if (value == correctText) {
                    _cancelableOperation!.cancel();
                    Navigator.of(context)
                        .pop(); // close after getting currect text
                  }
                },
              ),
            );
          },
        );
      },
    );
  }
于 2021-11-22T16:01:13.323 回答