简体   繁体   English

如何从 flutter 的文本字段中显示验证错误消息

[英]how to display validation error message out from the textfield in flutter

在此处输入图像描述

how to display "this field is required" message out from the box.如何从框中显示“此字段为必填项”消息。 this message will display on button click.此消息将在按钮单击时显示。

here is the textfield code这是文本字段代码

-------------------EDITED QUESTION------------------- -------------------编辑的问题-------------------

Here is your code and modified it by adding one more textformfield这是您的代码,并通过添加一个 textformfield 对其进行了修改

import 'package:flutter/material.dart';



class ExperimentApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        scaffoldBackgroundColor: Colors.white,
      ),
      home: ExperimentHome(),
    );
  }
}

class ExperimentHome extends StatelessWidget {
  final GlobalKey<FormFieldState> formFieldKey = GlobalKey();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Row(
          children: [
            Expanded(
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: RoundedInputField(
                  formFieldKey: formFieldKey,
                  icon: Icons.edit,
                  labelText: 'Label',
                  validate: (value) {
                    if (value == null || value.isEmpty) {
                      return "This field is required";
                    }
                    return null;
                  },
                ),
              ),
            ),
//this is one more TextFormField
            RoundedInputField(
                  formFieldKey: formFieldKey,
                  icon: Icons.edit,
                  labelText: 'Label1',
                  validate: (value) {
                    if (value == null || value.isEmpty) {
                      return "This field is required";
                    }
                    return null;
                  },
                ),
            
            IconButton(
              icon: Icon(Icons.check),
              onPressed: () {
                // you need to call `.validate` to actually validate the field.
                formFieldKey.currentState.validate();
              },
            )
          ],
        ),
      ),
    );
  }
}

class RoundedInputField extends StatelessWidget {
  final IconData icon;
  final FormFieldValidator<String> validate;
  final String labelText;

  final GlobalKey<FormFieldState> formFieldKey;

  // (before flutter 2.0) drop `required`
  const RoundedInputField({
    Key key,
    @required this.formFieldKey,
    
    
    @required this.labelText,
    @required this.icon,
    @required this.validate,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      key: formFieldKey,
      validator: validate,
      decoration: InputDecoration(
        icon: Icon(
          icon,
          color: Colors.blue,
        ),
        labelText: labelText,
      ),
    );
  }
}

this is error这是错误

════════ Exception caught by rendering library ═════════════════════════════════
RenderBox was not laid out: RenderTransform#3842d NEEDS-LAYOUT NEEDS-PAINT
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1940 pos 12: 'hasSize'

The relevant error-causing widget was
TextFormField-[LabeledGlobalKey<FormFieldState<dynamic>>#a4b32]
lib\abc.dart:87
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════
Multiple widgets used the same GlobalKey.
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════
Multiple widgets used the same GlobalKey.
════════════════════════════════════════════════════════════════════════════════

and it shows a plain white screen as output它显示纯白屏幕为 output

This will work for you.这对你有用。


 decoration: InputDecoration(
                                      focusedBorder: UnderlineInputBorder(
                                        borderSide: BorderSide(
                                            color: Colors.anyColor,
                                            width: 2),
                                      ),
                                      focusedErrorBorder: UnderlineInputBorder(
                                        borderSide: BorderSide(
                                            color: Colors.anyColor,
                                            width: 2),
                                      ),
                                      errorBorder:
                                          (value.isEmpty)
                                              ? UnderlineInputBorder(
                                                  borderSide: BorderSide(
                                                      color: Colors.anyColor),
                                                )
                                              : InputBorder.none,
                                      errorText:
                                          (value.isEmpty)
                                              ? "Minimum 3 characters required"
                                              : null,
                                      errorStyle: anyTextStyle(),
                                      hintText: "Name",
                                      hintStyle:
                                          anyTextStyle()),

You need to use a GlobalKey<FormFieldState> and actually call .validate on the field to validate the field.您需要使用GlobalKey<FormFieldState>并在该字段上实际调用.validate来验证该字段。

When you call .validate , the TextFormField will validate the field and show the error message if the validate method returns a String .当您调用.validate时, TextFormField将验证该字段并在 validate 方法返回String时显示错误消息。

More on TextFormField : https://api.flutter.dev/flutter/material/TextFormField-class.html有关TextFormField的更多信息: https://api.flutter.dev/flutter/material/TextFormField-class.html

Code Sample (there are some syntatic differences as you seem to be using an older version of dart):代码示例(存在一些语法差异,因为您似乎使用的是旧版本的 dart):

import 'package:flutter/material.dart';

void main() async {
  runApp(ExperimentApp());
}

class ExperimentApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        scaffoldBackgroundColor: Colors.white,
      ),
      home: ExperimentHome(),
    );
  }
}

class ExperimentHome extends StatelessWidget {
  final GlobalKey<FormFieldState> formFieldKey = GlobalKey();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Row(
          children: [
            Expanded(
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: RoundedInputField(
                  formFieldKey: formFieldKey,
                  icon: Icons.edit,
                  labelText: 'Label',
                  validate: (value) {
                    if (value == null || value.isEmpty) {
                      return "This field is required";
                    }
                    return null;
                  },
                ),
              ),
            ),
            IconButton(
              icon: Icon(Icons.check),
              onPressed: () {
                // you need to call `.validate` to actually validate the field.
                formFieldKey.currentState!.validate();
              },
            )
          ],
        ),
      ),
    );
  }
}

class RoundedInputField extends StatelessWidget {
  final IconData icon;
  final FormFieldValidator<String> validate;
  final String labelText;

  final GlobalKey<FormFieldState> formFieldKey;

  // (before flutter 2.0) drop `required`
  const RoundedInputField({
    Key? key,
    required this.formFieldKey,
    required this.labelText,
    required this.icon,
    required this.validate,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      key: formFieldKey,
      validator: validate,
      decoration: InputDecoration(
        icon: Icon(
          icon,
          color: Colors.blue,
        ),
        labelText: labelText,
      ),
    );
  }
}

So, finally i got the solution.所以,最后我得到了解决方案。 here it works perfectly.在这里它完美地工作。

TextFormField widget TextFormField 小部件

import 'package:attendance_system_app/text_field_container.dart';
import 'package:flutter/material.dart';

class RoundedInputField extends StatelessWidget {
  final String hintText;
  final IconData icon;
  final ValueChanged<String> onChanged;
  final TextEditingController controller;
  final double fontsize;
  final FormFieldValidator<String> validate;
  final String errortext;
  final String labelText;
  final GlobalKey<FormFieldState> formFieldKey;
  //final  onsaved;

  const RoundedInputField({Key key,this.labelText, this.formFieldKey,    this.errortext,this.hintText, this.icon,this.validate, this.onChanged,this.controller,this.fontsize})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return TextFormField(
    decoration: InputDecoration(
          labelText: labelText,
          fillColor: Colors.blue[50],
        
          
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(29.0),
          ),
          // errorBorder:
          //     OutlineInputBorder(borderSide: BorderSide(color: Colors.purple)),
          // focusedErrorBorder:
          //     OutlineInputBorder(borderSide: BorderSide(color: Colors.purple)),
          // errorStyle: TextStyle(color: Colors.purple),
        ),
        //controller: controller,
        validator: validate,
        controller: controller,
        maxLength: 5,
      
        //onSaved: (String ?onsaved);
      );
    //TextEditingController namecontroller = new TextEditingController();
    //return TextFieldContainer(
     
      // child: TextFormField(
      //    key: formFieldKey,
      //   onChanged: onChanged,
      //   cursorColor: Colors.black,
        
      //   style: TextStyle(fontSize: 16),
        
      //   controller: TextEditingController(),
      //  validator: validate,
      //  obscureText: true,
      //   decoration: InputDecoration(
      //     icon: Icon(
      //       icon,
      //       color: Colors.blue,
      //     ),
      //     hintText: hintText,
      //     border: InputBorder.none,
      //     //labelText: labeltext
      //     errorText: errortext,
      //     labelText: labelText,
          
                  
      //   ),
      // ),
    //);
  }
}

and here u can call the widget.在这里你可以调用小部件。

class JafPersonals extends StatefulWidget {


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

class _JafPersonalState extends State<JafPersonals> {
TextEditingController _applicantName=new TextEditingController();
  TextEditingController _fatherName=new TextEditingController();
final GlobalKey<FormState> _formkey=GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      drawer: new AdminDrawerCode(),
      appBar: AppBar(
       title: Image.asset("assets/image/company_logo.png",height: 140,width: 280,
       ),
      
       //automaticallyImplyLeading: false,
       backgroundColor: Colors.white,
       iconTheme: IconThemeData(color: Colors.blue,size: 20),
       //leading: new Icon(Icons.menu,color: Colors.blue,),
       actions: <Widget>[
       IconButton(
        icon: Icon(
        Icons.notifications,
        color: Colors.blue,
        size:26
      ),
      onPressed: () {
        // do something
      },
      
    )
    ],
    ),
    body: Form(
          key: _formkey,
          
          //autovalidateMode: AutovalidateMode.onUserInteraction,
          child: ListView(
            padding: EdgeInsets.all(16),
            children: [
              Text(" Employee Bio Data",style: TextStyle(fontSize: 30,fontWeight: FontWeight.bold,color: Colors.blue[900])),
              SizedBox(height: 20,),
               Text(" Personal data",style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold,color: Colors.blue[900])),
              SizedBox(height: 20,),
              RoundedInputField(labelText: 'Applicant name',controller: _applicantName,
              validate: (value) {
              if (value.length < 4) {
                return 'Enter at least 4 characters';
              } else {
                return null;
              }
        },),
        SizedBox(height: 10),
      
        RoundedInputField(labelText: 'Father name',controller: _applicantName,
              validate: (value) {
              if (value.length < 4) {
                return 'Enter at least 4 characters';
              } else {
                return null;
              }
        },),
RoundedButton(text: 'Submit',
        press: (){
          final isvalid=_formkey.currentState.validate();
          if(isvalid){
            _formkey.currentState.save();
            Navigator.push(context, MaterialPageRoute(builder: (context)=>JafFamily()));

          }
          
        },)
              
            ]
          )
    ));
  }
}

this code resolve my problem.这段代码解决了我的问题。 happy coding!!编码快乐!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM