Flutter 中的文本字段验证

Posted

技术标签:

【中文标题】Flutter 中的文本字段验证【英文标题】:Textfield validation in Flutter 【发布时间】:2019-04-24 18:44:39 【问题描述】:

我正在开发 Flutter TextField 小部件。如果用户没有填写TextField,我想在TextField 小部件下方显示一条错误消息。在这种情况下,我只需要使用 TextField Widget 而不是 TextFormField

【问题讨论】:

【参考方案1】:

你想要的一个最小的例子:

class MyHomePage extends StatefulWidget 
  @override
  MyHomePageState createState() 
    return new MyHomePageState();
  


class MyHomePageState extends State<MyHomePage> 
  final _text = TextEditingController();
  bool _validate = false;

  @override
  void dispose() 
    _text.dispose();
    super.dispose();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text('TextField Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Error Showed if Field is Empty on Submit button Pressed'),
            TextField(
              controller: _text,
              decoration: InputDecoration(
                labelText: 'Enter the Value',
                errorText: _validate ? 'Value Can\'t Be Empty' : null,
              ),
            ),
            RaisedButton(
              onPressed: () 
                setState(() 
                  _text.text.isEmpty ? _validate = true : _validate = false;
                );
              ,
              child: Text('Submit'),
              textColor: Colors.white,
              color: Colors.blueAccent,
            )
          ],
        ),
      ),
    );
  

【讨论】:

这在errorText: _validate ? 'Value Can\'t Be Empty' : null, 行显示“无效常量值”错误 @RezaMortazavi 在 InputDecoration 之前删除 const 让我们在setState的示例中编写一些干净的代码:_validate = _text.text.isEmpty【参考方案2】:

Flutter 自己处理错误文本,因此我们不需要使用变量 _validate。它会在运行时检查你是否满足条件。

final confirmPassword = TextFormField(
  controller: widget.confirmPasswordController,
  obscureText: true,
  decoration: InputDecoration(
    prefixIcon: Icon(Icons.lock_open, color: Colors.grey),
    hintText: 'Confirm Password',
    errorText: validatePassword(widget.confirmPasswordController.text),
    contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
  ),
);

String validatePassword(String value) 
  if (!(value.length > 5) && value.isNotEmpty) 
    return "Password should contain more than 5 characters";
  
  return null;

注意:用户必须添加至少一个字符才能收到此错误消息。

【讨论】:

这是使用 - TextFormField 问题是关于不使用 - TextFormField @anmol.majhail:添加了更多与 TextFormField 相关的信息,这将对其他人有所帮助。 我确认它也适用于由 FormField 包装的 TextField。 @jitsm555 可以重构它以获得更好的答案。 TextField 一起工作,甚至不使用 FormField 包装,只是改变看起来它们可以互换使用或几乎没有区别 @jitsm555 这看起来不错,但我们应该如何从 RaisedButton 的按下方法调用 validatePassword 方法?【参考方案3】:

我会考虑使用TextFormFieldvalidator

例子:

class MyHomePageState extends State<MyHomePage> 
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text('TextFormField validator'),
      ),
      body: Form(
        key: _formKey,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            TextFormField(
              decoration: InputDecoration(
                hintText: 'Enter text',
              ),
              textAlign: TextAlign.center,
              validator: (text) 
                if (text == null || text.isEmpty) 
                  return 'Text is empty';
                
                return null;
              ,
            ),
            RaisedButton(
              onPressed: () 
                if (_formKey.currentState.validate()) 
                  // TODO submit
                
              ,
              child: Text('Submit'),
            )
          ],
        ),
      ),
    );
  

【讨论】:

如果您需要在提交时验证多个字段的最佳解决方案。【参考方案4】: 如果您使用TextFormField,那么您可以轻松实现“错误” 在您的文本字段下方。 您可以在不使用 _validate 或任何其他标志的情况下执行此操作。 在这个例子中,我使用了TextFormFieldvalidator方法 小部件。这使得工作更加容易和可读 同一时间。 我还使用了FormState,让工作更轻松
void main() 
  runApp(MyApp());


class MyApp extends StatelessWidget 
  final _form = GlobalKey<FormState>(); //for storing form state.

//saving form after validation  
void _saveForm() 
    final isValid = _form.currentState.validate();
    if (!isValid) 
      return;
    
  

  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      home: Scaffold(
        body: Form(
          key: _form, //assigning key to form

          child: ListView(
            children: <Widget>[

              TextFormField(
                decoration: InputDecoration(labelText: 'Full Name'),
                validator: (text) 
                  if (!(text.length > 5) && text.isNotEmpty) 
                    return "Enter valid name of more then 5 characters!";
                  
                  return null;
                ,
              ),

              TextFormField(
                decoration: InputDecoration(labelText: 'Email'),
                validator: (text) 
                  if (!(text.contains('@')) && text.isNotEmpty) 
                    return "Enter a valid email address!";
                  
                  return null;
                ,
              ),

              RaisedButton(
                child: Text('Submit'),
                onPressed: () => _saveForm(),
              )
            ],
          ),
        ),
      ),
    );
  


我希望这会有所帮助!

【讨论】:

这应该是唯一可以接受的答案。其余的答案似乎都是子解决方案。此解决方案实际上可用于验证更大的表单。谢谢 但他明确表示,他不需要TextFormField【参考方案5】:

你可以这样做

class _validateTextField extends State<validateTextField> 
  TextEditingController userNameController = TextEditingController();
  bool userNameValidate = false;

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
          child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                TextField(
                  controller: userNameController,
                  decoration: InputDecoration(
                      labelText: 'Enter Username',
                      errorText: isUserNameValidate ? 'Please enter a Username' : null
                  ),
                ),
                SizedBox(height: 50,),
                OutlineButton(
                  onPressed: () 
                    validateTextField(userNameController.text);
                  ,
                  child: Text('Validate'),
                  textColor: Colors.blue,
                ),
              ]
          )
      ),
    );
  

创建函数 - 此函数将验证您输入的值是否有效。并在点击提交或验证按钮时调用它

  bool validateTextField(String userInput) 
    if (userInput.isEmpty) 
      setState(() 
        isUserNameValidate = true;
      );
      return false;
    
    setState(() 
      isUserNameValidate = false;
    );
    return true;
  

【讨论】:

以上是关于Flutter 中的文本字段验证的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:表单验证同时验证所有文本字段

Flutter 中的自动填充文本字段

ListView 包含一个多行文本字段,后跟 Flutter 中的 ListTiles

Flutter 日期选择器验证

带有 Flutter 的 Firebase 中的唯一用户名

当在文本字段中输入字段中的数据时,Flutter Firestore 显示文档 ID