Flutter TextFormField Validator 在文本为空或 null 时显示错误 suffixIcon

Flutter TextFormField Validator show error suffixIcon on text empty or null

我有一个颤动 TextFormField 并且我已经显示错误并且当文本为空或为空时轮廓边框颜色变为红色。我想要的是在 TextFormField 为空时也显示 suffixIcon

下面是我的代码


class Login extends StatefulWidget {
  const Login({Key? key}) : super(key: key);

  @override
  _LoginState createState() => _LoginState();
}

class _LoginState extends State<Login> {
  final loginFormKey = GlobalKey<FormState>();

  TextEditingController userNameController = TextEditingController();

  FocusNode userNameFocusNode = FocusNode();

  bool userNameHasFocus = false;

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
    userNameController.dispose();
    userNameFocusNode.dispose();
  
  }

  @override
  Widget build(BuildContext context) {
  
    return Scaffold(
      backgroundColor: Colors.white,
      body: SingleChildScrollView(
          child: Center(
              child: Form(
                  autovalidateMode: AutovalidateMode.onUserInteraction,
                  key: loginFormKey,
                  child: Column(
                    children: [
                      Container(
                          padding: const EdgeInsets.all(1),
                          margin: const EdgeInsets.only(top: 5, bottom: 5),
                          child: const Text(
                            "Welcome to my app",
                            textAlign: TextAlign.center,
                          )),
                      Container(
                          margin: const EdgeInsets.only(
                              top: 1, bottom: 2, right: 1, left: 10),
                          child: TextFormField(
                            focusNode: userNameFocusNode,
                            controller: userNameController,
                            decoration: InputDecoration(
                              labelText: "Please Enter Username",
                              border: OutlineInputBorder(),
                            ),
                            validator: (phoneNo) {
                              if (phoneNo!.isEmpty) {
                                userNameFocusNode.requestFocus();
                                userNameHasFocus = true;
                                return "You must enter username";
                              } else {
                                userNameHasFocus = false;
                                return null;
                              }
                            },
                          )),
                      Container(
                          margin: const EdgeInsets.only(
                              top: 2, bottom: 1, right: 10, left: 10),
                          child: ElevatedButton(
                              onPressed: () {

                                if (loginFormKey.currentState!.validate()) {

                                  print(proceed)

                                }

                              },
                              child: Text("Login"),
                              style: ElevatedButton.styleFrom(
                                shape: StadiumBorder(),
                              )))
                    ],
                  )))),
    );
  }
}

我感兴趣的部分在下面validator


validator: (phoneNo) {
                              if (phoneNo!.isEmpty) {
                                userNameFocusNode.requestFocus();
                                userNameHasFocus = true;
                                return "You must enter username";
                              } else {
                                userNameHasFocus = false;
                                return null;
                              }
                            },

如果 phoneNo!.isEmpty 我应该在下面显示类似的内容


 suffixIcon: Icon(Icons.error_outline_rounded, color: Colors.red)

您可以使用 bool 来显示 suffixIcon

  bool showSuffix = false;
  
  @override
  void initState() {
    super.initState();
    userNameController.addListener(() {
      if (userNameController.text.isEmpty) {
        showSuffix = true;
      } else {
        showSuffix = false;
      }
      setState(() {});
    });
  }

 ///.........

 /// aslo can be used [Visibility] widget
 suffixIcon: showSuffix
    ? const Icon(Icons.error_outline_rounded,
        color: Colors.red)
    : null,

如果TextFormField是否有效,您需要根据条件显示或隐藏图标。

删除 autovalidateMode: AutovalidateMode.onUserInteraction 并添加 onChanged 方法,如下所示:

import 'package:flutter/material.dart';

class Login extends StatefulWidget {
  const Login({Key? key}) : super(key: key);

  @override
  _LoginState createState() => _LoginState();
}

class _LoginState extends State<Login> {
  final loginFormKey = GlobalKey<FormState>();

  TextEditingController userNameController = TextEditingController();

  FocusNode userNameFocusNode = FocusNode();

  bool userNameHasFocus = false;
  bool validated = true;

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
    userNameController.dispose();
    userNameFocusNode.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: SingleChildScrollView(
        child: Center(
          child: Form(
            key: loginFormKey,
            child: Column(
              children: [
                Container(
                    padding: const EdgeInsets.all(1),
                    margin: const EdgeInsets.only(top: 5, bottom: 5),
                    child: const Text(
                      "Welcome to my app",
                      textAlign: TextAlign.center,
                    )),
                Container(
                    margin: const EdgeInsets.only(top: 1, bottom: 2, right: 1, left: 10),
                    child: TextFormField(
                      focusNode: userNameFocusNode,
                      controller: userNameController,
                      decoration: InputDecoration(
                          labelText: "Please Enter Username",
                          border: const OutlineInputBorder(),
                          suffixIcon: !validated ? const Icon(Icons.error_outline_rounded, color: Colors.red) : const SizedBox()),
                      validator: (phoneNo) {
                        if (phoneNo!.isEmpty) {
                          userNameFocusNode.requestFocus();
                          userNameHasFocus = true;
                          return "You must enter username";
                        } else {
                          userNameHasFocus = false;
                          return null;
                        }
                      },
                      onChanged: (value) {
                        if (value.isNotEmpty) {
                          setState(() {
                            validated = true;
                            loginFormKey.currentState!.validate();
                          });
                        }
                      },
                    )),
                Container(
                  margin: const EdgeInsets.only(top: 2, bottom: 1, right: 10, left: 10),
                  child: ElevatedButton(
                    onPressed: () {
                      if (loginFormKey.currentState!.validate()) {
                        setState(() {
                          validated = loginFormKey.currentState!.validate();
                        });
                      } else {
                        setState(() {
                          validated = loginFormKey.currentState!.validate();
                        });
                      }
                    },
                    child: const Text("Login"),
                    style: ElevatedButton.styleFrom(
                      shape: const StadiumBorder(),
                    ),
                  ),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}

编码愉快!!