Flutter注册按钮中如何添加CircularProgressIndicator加载动画
实现思路
通过State级别的布尔变量标记异步请求状态,动态切换按钮的显示内容和可点击状态,同时在异步请求的完整生命周期内正确维护状态值即可实现需求。
你现有代码的核心问题是:isLoading = false逻辑写在了异步请求外侧,请求还未执行完成就会触发状态更新,加载动画刚显示就会消失;同时缺失isLoading、输入控制器等必要的状态变量声明。
具体修改步骤
步骤1:补充State类的成员变量
在_SignUpState类顶部添加以下声明:
// 加载状态标记 bool isLoading = false; // 密码显隐标记 bool _isHidden = true; // 输入框控制器 final TextEditingController _emailController = TextEditingController(); final TextEditingController _nameController = TextEditingController(); final TextEditingController _phoneController = TextEditingController(); final TextEditingController _usernameController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); final TextEditingController _password_confirmationController = TextEditingController(); final TextEditingController _adressController = TextEditingController();
步骤2:修改注册按钮代码
将原RaisedButton部分替换为以下代码,加载时自动切换为进度指示器并禁用点击:
RaisedButton( textColor: Colors.white, color: kPrimaryColor, child: isLoading ? const CircularProgressIndicator(color: Colors.white) : const Text("S'inscrire"), onPressed: isLoading ? null : () { if (_formKey.currentState.validate()) { registerUser(); } }, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30.0), ), )
步骤3:修正异步请求逻辑
替换原registerUser方法,用try-catch-finally保证无论请求成功、失败,都能正确重置加载状态:
void registerUser() async { setState(() { isLoading = true; }); try { String email = _emailController.text; String password = _passwordController.text; String name = _nameController.text; String username = _usernameController.text; String phone = _phoneController.text; String adress = _adressController.text; String password_confirmation = _password_confirmationController.text; final user = await authentication.register( name, email, phone, password, password_confirmation, username, adress ); if (user != null) { if(mounted) { Navigator.push(context, MaterialPageRoute(builder: (context) => LoginPage())); ScaffoldMessenger.of(context).showSnackBar(snackBar); } } } catch (error) { if(mounted) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(error.toString()))); } } finally { // 页面未销毁的情况下重置加载状态 if(mounted) { setState(() { isLoading = false; }); } } }
内容的提问来源于stack exchange,提问作者lucky
相关产品推荐
相关产品推荐

