【问题标题】:how to create resuable textfield with validator in flutter如何在颤动中创建具有验证的可重用文本字段
【发布时间】:2021-08-20 07:30:32
【问题描述】:

我正在创建一个包含用户名和密码字段的登录表单,我想在用户跳过任何字段时添加验证。我创建了这个可重复使用的文本字段。

class RoundedInputField extends StatelessWidget {
  final String hintText;
  final ValueChanged<String> onChanged;
  final TextEditingController controller;
  final FormFieldValidator validate;
  const RoundedInputField({Key key, this.hintText,
    this.onChanged,
   this.controller,this.validate,
 
  })
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return TextFieldContainer(
      child: TextFormField(
        onChanged: onChanged,            
        controller: TextEditingController(),
        validator: validate,
        decoration: InputDecoration(
          hintText: hintText,
          border: InputBorder.none,
        ),
      ),
    );
  }
}

这样称呼它

 RoundedInputField(hintText: "Username",icon: Icons.email,fontsize: 20,
                controller: TextEditingController(text: user.username),
                onChanged: (value){
                  user.username=value;
                },
                validate: (value){
                  if(value.isEmpty){
                    return "This field is required";
                  }
                },
                ),

但是验证器属性不能正常工作,在这里。

如果有人知道如何解决它,请帮助!

【问题讨论】:

    标签: flutter validation textfield


    【解决方案1】:

    我一直在以这样的可重用方式使用 TextFormField,它为我提供了我需要的所有目的,我认为它也适用于您的情况

    class BoxTextField extends StatelessWidget {
      final TextEditingController controller;
      final FormFieldValidator<String> validator;
      final bool obsecure;
      final bool readOnly;
      final VoidCallback onTap;
      final VoidCallback onEditingCompleted;
      final TextInputType keyboardType;
      final ValueChanged<String> onChanged;
      final bool isMulti;
      final bool autofocus;
      final bool enabled;
      final String errorText;
      final String label;
      final Widget suffix;
      final Widget prefix;
    
      BoxTextField(
          {Key key,
          this.controller,
          this.validator,
          this.keyboardType = TextInputType.text,
          this.obsecure = false,
          this.onTap,
          this.isMulti = false,
          this.readOnly = false,
          this.autofocus = false,
          this.errorText,
          @required this.label,
          this.suffix,
          this.prefix,
          this.enabled = true,
          this.onEditingCompleted,
          this.onChanged})
          : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          margin: EdgeInsets.symmetric(vertical: 4),
          child: TextFormField(
              onChanged: onChanged,
              onEditingComplete: onEditingCompleted,
              autofocus: autofocus,
              minLines: isMulti ? 4 : 1,
              maxLines: isMulti ? null : 1,
              onTap: onTap,
              enabled: enabled,
              readOnly: readOnly,
              obscureText: obsecure,
              keyboardType: keyboardType,
              controller: controller,
              decoration: InputDecoration(
                errorText: errorText,
                prefixIcon: prefix,
                suffixIcon: suffix,
                labelStyle: TextStyle(fontSize: lableFontSize()),
                labelText: label,
                hintStyle: TextStyle(color: Colors.blueGrey, fontSize: 15),
                contentPadding: EdgeInsets.symmetric(vertical: 8, horizontal: 20),
                enabledBorder: textFieldfocused(),
                border: textFieldfocused(),
                focusedBorder: textFieldfocused(),
                errorBorder: errorrTextFieldBorder(),
                focusedErrorBorder: errorrTextFieldBorder(),
              ),
              validator: validator),
        );
      }
    }
    

    这是用法

    class LoginScreen extends StatefulWidget {
      @override
      _LoginScreenState createState() => _LoginScreenState();
    }
    
    class _LoginScreenState extends State<LoginScreen> {
      TextEditingController _emailPhone = new TextEditingController();
      TextEditingController _password = new TextEditingController();
    
      GlobalKey<FormState> _formKey = new GlobalKey<FormState>();
    
      @override
      void initState() {
        super.initState();
      }
    
      String loginError;
      bool loggingIn = false;
    
      @override
      Widget build(BuildContext context) {
        return CustomScrollView(
          slivers: [
            SliverList(
                delegate: SliverChildListDelegate([
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 20.0),
                child: Form(
                    key: _formKey,
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        SizedBox(
                          height: 50,
                        ),
                        BoxTextField(
                          validator: (str) {
                            if (str.isEmpty) {
                              return tr('common.required');
                            }
    
                            return null;
                          },
                          controller: _emailPhone,
                          label: tr('login.username'),
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        BoxTextField(
                          label: tr('login.password'),
                          controller: _password,
                          obsecure: true,
                          validator: (str) {
                            if (str.isEmpty) {
                              return tr('common.required');
                            }
    
                            return null;
                          },
                        ),
             Center(
                            child: BoxButton(
                          loading: loggingIn,
                          lable: tr('login.btn'),
                          onPressed: () {
                              
                                },
                        )),
                      ],
                    )),
              )
            ]))
          ],
        );
      }
    }
    

    【讨论】:

    • 你能编辑你的代码吗,如何调用这个
    • 给我一分钟
    • 我已根据您的要求进行了编辑,我认为它解释了它
    【解决方案2】:

    替换您的代码并尝试以下操作:

    RoundedInputField(
                  hintText: "Username",
                  icon: Icons.email,
                  fontsize: 20,
                  controller: TextEditingController(text: user.username),
                  onChanged: (value) {
                    user.username = value;
                  },
                  validate: (value) {
                    if (value.isEmpty) {
                      return "This field is required";
                    }
                    return null;
                  },
                ),
    

    【讨论】:

    • 是“TextFieldContainer”是你的自定义小部件吗?
    • 将 return null 添加到 else 块...等待重写代码
    • 格式正确,但“此字段为必填项”会显示在哪里?
    • 实际上,我们需要从函数中返回一些东西。因此,无论何时填充该字段,在这种情况下,我们都需要返回 null。但是如果没有填写字段,那么只有我们会返回“此字段为必填项”。
    • 我这样做了,但是当我运行代码并将文本字段留空时,此消息“此字段是必需的”应该打印在该文本字段下方
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-21
    • 2019-08-22
    • 1970-01-01
    • 2021-02-12
    • 2022-01-21
    • 2021-08-24
    • 1970-01-01
    相关资源
    最近更新 更多