Flutter中TextEditingController值无法传递,Firebase邮箱登录异常
问题:Firebase邮箱/密码认证中输入框内容无法传递到按钮组件
在实现Firebase邮箱/密码认证时,输入框的emailController和passwordController内容无法传递到SubmitButton或TestButton中,点击按钮时打印的$email、$password及$textTest均为空。
问题原因
当前代码在LoginScreen的build方法中,直接将emailController.text.trim()和passwordController.text.trim()作为参数传给SubmitButton和TestButton。这会导致:
- 传递的是组件初始化时的空字符串
- 后续输入框内容变化时,由于
SubmitButton和TestButton是无状态组件(StatelessWidget),不会自动重建,因此始终持有初始的空值
解决方案
方法一:直接传递TextEditingController(推荐)
修改按钮组件,让它们接收TextEditingController而非直接接收文本值,这样在点击按钮时可以实时获取输入框的最新内容,同时避免不必要的组件重建。
修改SubmitButton
class SubmitButton extends StatelessWidget { SubmitButton({ Key? key, required this.emailController, required this.passwordController, }) : super(key: key); final TextEditingController emailController; final TextEditingController passwordController; final AuthService authService = AuthService(); @override Widget build(BuildContext context) { return ElevatedButton( onPressed: () async { // 点击时实时获取输入框最新内容 final email = emailController.text.trim(); final password = passwordController.text.trim(); try { print('onPress email = $email et password = $password'); // 替换硬编码的账号密码,使用实时获取的值 await authService.signInWithEmailAndPassword( email: email, password: password, ); Navigator.of(context).pushReplacement( MaterialPageRoute(builder: (context) => HomeScreen())); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(e.toString()), ), ); } }, child: const Text('Se connecter'), ); } }
修改TestButton
class TestButton extends StatelessWidget { TestButton({ Key? key, required this.emailController, }) : super(key: key); final TextEditingController emailController; @override Widget build(BuildContext context) { return ElevatedButton( onPressed: () async { try { final textTest = emailController.text.trim(); print('onPress email = $textTest'); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(e.toString()), ), ); } }, child: const Text('Test'), ); } }
更新LoginScreen中的按钮调用
// 替换原有的SubmitButton和TestButton代码 SubmitButton( emailController: emailController, passwordController: passwordController, ), TestButton( emailController: emailController, ),
方法二:监听输入框变化并更新状态
在LoginScreenState中监听输入框的内容变化,调用setState更新按钮的参数。这种方法会触发父组件重建,性能略逊于方法一。
修改LoginScreenState
class LoginScreenState extends State<LoginScreen> { final TextEditingController emailController = TextEditingController(); final TextEditingController passwordController = TextEditingController(); String email = ''; String password = ''; @override void initState() { super.initState(); // 监听输入框内容变化,更新状态 emailController.addListener(() { setState(() { email = emailController.text.trim(); }); }); passwordController.addListener(() { setState(() { password = passwordController.text.trim(); }); }); } @override void dispose() { emailController.dispose(); passwordController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Container( padding: const EdgeInsets.all(30), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ LoginEmail(emailController: emailController), const SizedBox(height: 30.0), LoginPassword(passwordController: passwordController), const SizedBox(height: 30.0), SubmitButton( email: email, password: password, ), TestButton( textTest: email, ), Flexible( child: LoginButton( text: 'Se connecter avec Google', icon: FontAwesomeIcons.google, color: Colors.blue, loginMethod: AuthService().googleLogin, ), ), ], ), ), ); } }
额外提示
原代码中SubmitButton的signInWithEmailAndPassword方法使用了硬编码的'myEmail'和'myPw',需要替换为实时获取的输入值,否则无法实现正常的账号密码登录逻辑。
内容的提问来源于stack exchange,提问作者Gautier Chuinard
相关产品推荐
相关产品推荐

