Flutter中的文本字段验证

sha*_*ini 19 dart flutter

我正在使用Flutter TextField小部件。TextField如果用户未填写,我想在小部件下方显示错误消息TextField。在这种情况下,我不必使用TextFieldWidget TextFormField

anm*_*ail 35

所需内容的最小示例:

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,
            )
          ],
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • @RezaMortazavi 在 InputDecoration 之前删除 const (3认同)
  • 让我们在 `setState` 的示例中编写一些干净的代码:`_validate = _text.text.isEmpty` (3认同)
  • 这在`errorText:_validate?行上显示“无效常量值”错误。“值不能为空”:null, (2认同)

jit*_*555 34

Flutter 本身会处理错误文本,因此我们不需要使用 variable _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;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这是使用 - `TextFormField` 问题是关于不使用 - `TextFormField` 的。 (5认同)

Erl*_*end 25

我会考虑将 aTextFormField与 a 一起使用validator

例子:

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'),
            )
          ],
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 15

  • 如果您使用,TextFormField那么您可以轻松实现“文本字段下方的错误”。
  • 您可以在不使用_validate或任何其他标志的情况下执行此操作。
  • 在这个例子中,我使用validatorTextFormField 小部件的方法。这使工作同时变得更加容易和可读。
  • 我也曾经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(),
              )
            ],
          ),
        ),
      ),
    );
  }
}

Run Code Online (Sandbox Code Playgroud)

我希望这有帮助!

  • 但他明确表示,他不需要 `TextFormField` (3认同)
  • 这应该是唯一可以接受的答案。其余答案似乎都是子解决方案。该解决方案实际上可以用于验证更大的表单。谢谢 (2认同)