Flutter:FutureBuilder 用于对话框中的进度指示器

Flutter: FutureBuilder for progress indicator in a dialog

提问人:Nimbus 提问时间:7/12/2023 最后编辑:Nimbus 更新时间:7/13/2023 访问量:37

问:

我正在为 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...
                      }
                    }),
              ],
            );
          }
        });
  }

}
Flutter 对话框 未来 进度 指示器

评论


答: 暂无答案