如何在 Flutter 中的用户名和密码字段出现错误时将“HintText”和“Border”颜色更改为红色?

问题描述 投票:0回答:1

问题:

我希望用户名和密码字段的

hintText
border
颜色在出现错误时都变为红色。但是,只有密码字段可以正常工作,而用户名字段没有反映预期的更改。

这是我当前看到的行为:

代码:

我正在使用自定义

TextFieldWidget
构建用户名和密码的文本字段:

class TextFieldWidget {
  static Widget buildTextField({
    required TextEditingController controller,
    required String fieldTitle,
    required String hintText,
    bool isPassword = false,
    required BuildContext context,
    bool obscureText = false,
    void Function()? toggleVisibility,
    String? errorText,
    String? Function(String?)? validator,
  }) {
    final hasError = errorText != null;

    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 10.5),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            fieldTitle,
            style: const TextStyle(
              color: Colors.black,
            ),
          ),
          const SizedBox(height: 8.0),
          TextFormField(
            controller: controller,
            obscureText: obscureText,
            decoration: InputDecoration(
              errorText: hasError ? errorText : null,
              errorStyle: const TextStyle(color: Colors.red),
              hintText: hintText,
              hintStyle: TextStyle(
                color: hasError ? Colors.red : Colors.black.withOpacity(0.8),
              ),
              filled: true,
              fillColor: hasError ? Colors.red.shade50 : Colors.grey.shade300,
              suffixIcon: isPassword
                  ? IconButton(
                      icon: Icon(
                        obscureText
                            ? Icons.visibility
                            : Icons.visibility_off,
                        color: hasError ? Colors.red : Colors.grey,
                      ),
                      onPressed: toggleVisibility,
                    )
                  : null,
              border: OutlineInputBorder(
                borderRadius: BorderRadius.circular(10.0),
                borderSide: BorderSide(
                  color: hasError ? Colors.red : Colors.transparent,
                  width: 1.5,
                ),
              ),
              enabledBorder: OutlineInputBorder(
                borderRadius: BorderRadius.circular(10.0),
                borderSide: BorderSide(
                  color: hasError ? Colors.red : Colors.grey,
                  width: 1.5,
                ),
              ),
              focusedBorder: OutlineInputBorder(
                borderRadius: BorderRadius.circular(10.0),
                borderSide: BorderSide(
                  color: hasError ? Colors.red : Colors.black,
                  width: 1.5,
                ),
              ),
              errorBorder: OutlineInputBorder(
                borderRadius: BorderRadius.circular(10.0),
                borderSide: const BorderSide(
                  color: Colors.red,
                  width: 1.5,
                ),
              ),
              focusedErrorBorder: OutlineInputBorder(
                borderRadius: BorderRadius.circular(10.0),
                borderSide: const BorderSide(
                  color: Colors.red,
                  width: 1.5,
                ),
              ),
            ),
            validator: validator,
            style: TextStyle(
              color: hasError ? Colors.red : Colors.black,
            ),
          ),
        ],
      ),
    );
  }
}

我如何使用这些字段:

TextFieldWidget.buildTextField(
  controller: _userNameController,
  fieldTitle: 'Username',
  hintText: 'Enter your username',
  context: context,
  errorText: _usernameError, // Error text if any
  validator: (value) {
    if (value == null || value.trim().isEmpty) {
      return 'Username is required';
    }
    return null;
  },
),

const SizedBox(height: 15.0),

TextFieldWidget.buildTextField(
  controller: _passwordController,
  fieldTitle: 'Password',
  hintText: 'Enter your password',
  isPassword: true,
  context: context,
  obscureText: obscureText,
  toggleVisibility: () {
    ref.read(obscureTextProvider.notifier).state = !obscureText;
  },
  errorText: _passwordError,
),

OnSubmit 函数

Future<void> _onSubmit() async {
  setState(() {
    _usernameError = null;
    _passwordError = null;
  });

  bool isFormValid = _formKey.currentState!.validate();

  if (isFormValid) {
    final name = _userNameController.text;
    final password = _passwordController.text;

    try {
      await ref.read(authProvider).login(name, password, rememberMe: _rememberMe);
      Navigator.pushReplacement(
        context,
        MaterialPageRoute(builder: (_) => const HomeMainScreen()),
      );
    } catch (e) {
      setState(() {
        _errorMessage = e.toString();
        if (_errorMessage!.contains('username')) {
          _usernameError = _errorMessage;
        } else if (_errorMessage!.contains('password')) {
          _passwordError = _errorMessage;
        }
      });
    }
  }
}

问题:

密码字段按预期显示错误,但当出现错误时,用户名字段不会将红色应用于

hintText
border
。我缺少什么?如何确保用户名和密码字段以相同的方式显示错误?


使用的变量:

String? _errorMessage;
String? _usernameError;
String? _passwordError;
late TextEditingController _userNameController;
late TextEditingController _passwordController;

预期行为:

  • 出现错误时,两个字段都应显示红色
    hintText
    和红色边框。

当前行为:

  • 只有密码字段按预期工作,而用户名字段没有反映红色边框和
    hintText

任何指导将不胜感激!

flutter dart user-interface error-handling riverpod
1个回答
0
投票

我认为这可能是因为在用户名的验证器参数上,您只是验证它应该为 null 或空字符串,否则会出现错误。我建议首先在验证器条件中强制执行错误,以查看颜色是否发生变化。在您显示的屏幕截图中,用户名包含一个字符串,因此不会错误。 如果仍然没有显示颜色,也许您也可以尝试将“_usernameError”变量添加到验证器中

© www.soinside.com 2019 - 2024. All rights reserved.