首页 > 解决方案 > 如果我在 TextField 的“onChange”中调用“setState”,第一个字母会丢失

问题描述

我有 2 个文本字段,电子邮件和密码。输入电子邮件并且用户转到密码字段后,我在密码文本字段小部件下方显示默认消息“密码不得为空”。我想在用户开始输入密码时隐藏此消息。

注意:我必须使用 Textfield 小部件。这是代码:

@override
Widget build(BuildContext context) {
final TextEditingController emailController =
    new TextEditingController(text: this._email);
final TextEditingController passwordController =
    new TextEditingController();

final submit = () async {
  try {
    FauiUser user = await fauiSignInUser(
      apiKey: this.widget.firebaseApiKey,
      email: emailController.text,
      password: passwordController.text,
    );
  } catch (e) {
    this.setState(() {
      this._error = FauiError.exceptionToUiMessage(e);
      //after typing email, when user presses <enter> or clicks in the Password field, the default message "Password must not be empty"
      //is assigned to this._error and displayed below Password Textfield widget
      this._email = emailController.text;
    });
  }
};

return Column(
    children: <Widget>[
      TextField(
        controller: emailController,
        autofocus: true,
        decoration: InputDecoration(
          labelText: 'EMail',
        ),
        onSubmitted: (s) {
          submit();
        },
      ),
      TextField(
        controller: passwordController,
        obscureText: true,
        decoration: InputDecoration(
          labelText: 'Password',
        ),
        onSubmitted: (s) {
          submit();
        },
      ),
      RaisedButton(
        child: Text('Sign In'),
        onPressed: submit,
      ),
    ]);

} }

我尝试添加以下代码:

onChanged: (s) {
            if (this._error.isNotEmpty) {
              setState(() {
                this._error = "";
              }); //to hide the default message below Password widget
            }
          },

这将重建屏幕,消息消失,但 passwordController.text 被初始化,并且在重建之前输入的第一个字符在该过程中丢失(例如,如果用户键入“hello”,则值变为“ello”)。如何修复代码以使第一个字母不丢失?

标签: validationflutterdarterror-handlingtextfield

解决方案


我意识到通过使用 Focus,我可以达到类似的效果:

            child: TextField(
              controller: passwordController,
              obscureText: true,
              decoration: InputDecoration(
                labelText:"Password",
              ),
              onSubmitted: (s) {
                submit();
              },
            ),
            onFocusChange: (hasFocus) {
              if (hasFocus) {
                if (this._error.isNotEmpty) {
                  setState(() {
                    this._error = "";
                  });
                }}
            }),```



推荐阅读