提问人:Nimbus 提问时间:7/12/2023 最后编辑:Nimbus 更新时间:7/13/2023 访问量:37
Flutter:FutureBuilder 用于对话框中的进度指示器
Flutter: FutureBuilder for progress indicator in a dialog
问:
我正在为 Flutter 的 FutureBuilder 而苦苦挣扎。我想实现以下目标:
- 按下按钮后打开登录对话框(有效)
- 输入凭据并按“确定”后,在调用 Web 服务时显示进度指示器
- 从 Web 服务检索响应后,如果成功,请关闭对话框,否则显示错误消息
我已将 Web 服务配置为延迟 3 秒,因此我可以查看进度指示器。
目前发生的事情是:
- 按下登录按钮后,进度指示器显示 3 秒延迟,然后才会出现登录对话框
- 输入用户名和密码时,每个字符输入后,登录对话框(和键盘)消失,进度指示器显示 3 秒钟,然后登录对话框再次显示,可以输入下一个字符
- 最后,登录过程正常工作,但在调用 Web 服务时不显示进度指示器
在阅读了各种文档之后,我的印象是 FutureBuilder 只能处理在 initState 方法中调用一次的 future。就我而言,奇怪的是我在按下 Ok 按钮时调用 future 方法,并且我也在 FutureBuilder 的“future”参数中指定了这个 future。这是否有效或可能?
不幸的是,我找不到任何例子来说明我打算做的事情。我将非常感谢一些提示。提前非常感谢!
登录对话框是从应用栏调用的,如下所示:
IconButton(
icon: const Icon(Icons.login_rounded),
onPressed: () async {
showDialog(
context: context,
builder: (_) => const LoginDialog()).then((tokenResponse) async {
// further actions tbd...
});
},
)
登录对话框:
class LoginDialog extends StatefulWidget {
const LoginDialog({Key? key}) : super(key: key);
@override
LoginDialogState createState() {
return LoginDialogState();
}
}
class LoginDialogState extends State<LoginDialog> {
final _formKey = GlobalKey<FormState>();
final TextEditingController _userNameController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
String userName = "";
String password = "";
var logger = Logger();
final WebServiceUtil _webServiceUtil = WebServiceUtil();
Future login(String userName, String password) async {
dynamic responseObject;
try {
responseObject = await _webServiceUtil.login(userName, password);
} on Exception catch (e) {
// exception handling tbd...
}
return responseObject;
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: login(userName, password),
builder: (_, dataSnapshot) {
if (dataSnapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else {
return AlertDialog(
titlePadding: AppConstants.dialogTitlePadding,
contentPadding: AppConstants.dialogContentPadding,
elevation: AppConstants.dialogElevation,
insetPadding: AppConstants.dialogInsetPadding,
title: Text(AppLocalizations.of(context)!.login),
content: SingleChildScrollView(
child: Form(
key: _formKey,
child:
ListBody(mainAxis: Axis.vertical, children: <Widget>[
Text(AppLocalizations.of(context)!.loginText),
// the following methods called are simply creating
// text form fields with validators:
_buildUserNameTextField(),
_buildPasswordTextField()
]))),
actions: <Widget>[
TextButton(
child: Text(AppLocalizations.of(context)!.cancel),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: Text(AppLocalizations.of(context)!.ok),
onPressed: () async {
if (_formKey.currentState!.validate()) {
dynamic responseObject = await login(userName, password);
// further actions...
}
}),
],
);
}
});
}
}
答: 暂无答案
评论