我已经显示了一个对话框,如果有人正确键入某个单词,该对话框可以关闭。我想知道,如果有人在某个时间段内没有在第一个文本框中键入任何内容,是否可以显示第二个对话框。例如,如果此人在接下来的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.delay的新函数,我可以做一个"if"语句,但在没有输入文本的情况下,我找不到一种方法来做一个"if"语句。同样在这种情况下,我相信用户必须按下"回车"键,但我希望第二个对话框出现,因为用户没有触摸屏幕上的任何东西。这可能吗?
在简单的情况下,您可以通过传递相同的构建上下文来显示嵌套的重叠对话框。
第一个对话框将是
_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"),
),
);
}
这只是第一次检查用户交互。
如果你想使用时间框架,我们需要使用异步包来取消(而不是真正取消(未来。你可能会觉得它比第一个更复杂一点。
使用异步
_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
}
},
),
);
},
);
},
);
}