自动验证问题:使用Flutter中的自动验证进行密码和确认密码验证

时间:2018-12-10 10:22:30

标签: dart flutter cross-platform flutter-layout flutter-dependencies

我已经创建了 Form 窗口小部件,其中有多个 TextFormFeild 我创建了自定义 BoxFeild < / strong>。我遇到与Form Widget中的 auto-validation 相关的问题。在确认密码 BoxFeild

中无法验证密码匹配的字段

在将formKeyData保存在 validate password 之后,我应该 current state 进行匹配吗?

将密钥传递给BoxFeild构造函数时,我遇到了问题。它显示的多个小部件使用了相同的全局密钥。

我需要添加全局FormFeild键来比较_password_confirmPassword

class _PageSignUpState extends State<PageSignUp> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  var passKey = GlobalKey<FormFieldState>();

  bool _autoValidate = false;
  String _name, _email, _phoneNo, _password, _confirmPassoword;
  bool isLoading = false;

  final _passwordController = TextEditingController();
  final _confirmPassController = TextEditingController();

  double width,height;

  @override
  Widget build(BuildContext context) {


    width = MediaQuery.of(context).size.width;
    height = MediaQuery.of(context).size.height;

    return Scaffold(
      backgroundColor: Colors.white,
      body: Container(
        color: Colors.grey.shade200,
        child: Center(
          child: SingleChildScrollView(
            child: Container(
              child: Column(
                children: <Widget>[
                  Form(
                      key: _formKey,
                      autovalidate: _autoValidate,
                      child: Column(
                        children: <Widget>[
                          _nameWidget(),
                          _emailWidget(),
                          _passwordWidget(),
                          _confirmPassWidget(),
                          SizedBox(height: height/25),
                          _signUpButtonWidget()
                        ],
                      )),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  Container _signUpButtonWidget() {
    return Container(
      padding: EdgeInsets.symmetric(vertical: height / 40, horizontal: width / 15),
      width: double.infinity,
      child: RaisedButton(
        padding: EdgeInsets.all(12.0),
        child: Text(
          "Sign Up",
          style: TextStyle(color: Colors.white, fontSize: 20.0),
        ),
        color: Colors.blue,
        onPressed: () {
          setLoading(true);
          _validateInputs();
        },
      ),
    );
  }

  BoxFeild _confirmPassWidget() {
    return BoxFeild(
      hintText: "Confirm Password",
      lableText: "Confirm Password",
      obscureText: true,
      icon: Icons.lock_outline,
      validator: validatePasswordMatching,

      onSaved: (String val) {
        _confirmPassoword = val;
      },
    );
  }

  BoxFeild _passwordWidget() {
    return BoxFeild(
      key: passKey,
      hintText: "Enter Password",
      lableText: "Password",
      obscureText: true,
      icon: Icons.lock_outline,
      controller: _passwordController,
      validator: validatePassword,
      onSaved: (String val) {
        _password = val;
      },
    );
  }

  BoxFeild _emailWidget() {
    return BoxFeild(
      hintText: "Enter Email",
      lableText: "Email",
      keyboardType: TextInputType.emailAddress,
      icon: Icons.email,
      validator: validateEmail,
      onSaved: (String val) {
        _email = val;
      },
    );
  }

  BoxFeild _nameWidget() {
    return BoxFeild(
      hintText: "Enter Name",
      lableText: "Name",
      icon: Icons.person,
      validator: validateName,
      onSaved: (String val) {
        _name = val;
      },
    );
  }

  String validateName(String value) {
    String patttern = r'(^[a-zA-Z ]*$)';
    RegExp regExp = RegExp(patttern);
    if (value.length == 0) {
      return "Name is Required";
    } else if (!regExp.hasMatch(value)) {
      return "Name must be a-z and A-Z";
    }
    return null;
  }

  String validateEmail(String value) {
    RegExp regExp = RegExp(Constants.PATTERN_EMAIL, caseSensitive: false);

    if (value.length == 0) {
      return "Email is Required";
    } else if (!regExp.hasMatch(value)) {
      return "Enter valid email address.";
    }
    return null;
  }

  String validatePassword(String value) {
    if (value.length == 0) {
      return "Password is Required";
    } else if (value.length < 6) {
      return "Password Should be more than 6.";
    }
    return null;
  }


  String validatePasswordMatching(String value) {
    var password = passKey.currentState.value;

    if (value.length == 0) {
      return "Password is Required";
    } else if (value != password) {
      return 'Password is not matching';
    }
    return null;
  }



  void _validateInputs() {
    if (_formKey.currentState.validate()) {
      //If all data are correct then save data to out variables
      //Make a REST Api Call with success Go to Login Page after User Created.

        _formKey.currentState.save();
        setLoading(true);

        Utils.checkConnection().then((connectionResult) {
          if (connectionResult) {
          } else {
            setLoading(false);
            Utils.showAlert(context, "Flutter",
                "Internet is not connected. Please check internet connection.",
                    () {
                  Navigator.pop(context);
                }, true);
          }
        });


      } 




    } else {
//    If all data are not valid then start auto validation.
      setState(() {
        _autoValidate = true;
      });
    }
  }
}
  

BoxFeild.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class BoxFeild extends StatefulWidget {
  final TextEditingController controller;
  final FocusNode focusNode;
  final TextInputType keyboardType;
  final TextInputAction textInputAction;
  final TextCapitalization textCapitalization;
  final TextStyle style;
  final TextAlign textAlign;
  final bool autofocus;
  final bool obscureText;
  final bool autocorrect;
  final int maxLines;
  final Key key;
  final int maxLength;
  final bool maxLengthEnforced;
  final ValueChanged<String> onChanged;
  final VoidCallback onEditingComplete;
  final ValueChanged<String> onSubmitted;
  final List<TextInputFormatter> inputFormatters;
  final bool enabled;
  final IconData icon;
  final String hintText;
  final String lableText;
  final double cursorWidth;
  final Radius cursorRadius;
  final Color cursorColor;
  final Color defaultBorderColor;
  final Brightness keyboardAppearance;
  final EdgeInsets scrollPadding;
  final FormFieldValidator<String> validator;
  final ValueChanged<String> onFieldSubmitted;

  final FormFieldSetter<String> onSaved;

  const BoxFeild({
    this.key,
    this.controller,
    this.focusNode,
    TextInputType keyboardType,
    this.textInputAction,
    this.textCapitalization = TextCapitalization.none,
    this.style,
    this.icon,
    this.textAlign = TextAlign.start,
    this.autofocus = false,
    this.obscureText = false,
    this.autocorrect = true,
    this.maxLines = 1,
    this.maxLength,
    this.onSaved,
    this.hintText,
    this.lableText,
    this.maxLengthEnforced = true,
    this.onChanged,
    this.defaultBorderColor,
    this.onEditingComplete,
    this.onSubmitted,
    this.inputFormatters,
    this.enabled,
    this.cursorWidth = 2.0,
    this.cursorRadius,
    this.cursorColor,
    this.keyboardAppearance,
    this.scrollPadding,
    this.validator,
    this.onFieldSubmitted,
  })  : assert(textAlign != null),
        assert(autofocus != null),
        assert(obscureText != null),
        assert(autocorrect != null),
        assert(maxLengthEnforced != null),
        assert(maxLines == null || maxLines > 0),
        assert(maxLength == null || maxLength > 0),
        keyboardType = keyboardType ??
            (maxLines == 1 ? TextInputType.text : TextInputType.multiline);

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

class _BoxFeildState extends State<BoxFeild> {
  double width;
  double height;
  Color focusBorderColor =  Colors.grey.shade400;
  FocusNode _focusNode = FocusNode();
  ValueChanged<Colors> focusColorChange;
  @override
  void dispose() {
    super.dispose();
    _focusNode.dispose();
  }

  @override
  Widget build(BuildContext context) {
     width = MediaQuery.of(context).size.width;
     height = MediaQuery.of(context).size.height;

    return  Container(
      child:  Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          SizedBox(
            width: width / 30,
          ),
          Expanded(
              child: Container(
            margin: EdgeInsets.only(top: height / 400, bottom: height / 400, left: width / 50, right: width / 50),
            padding: EdgeInsets.all(height / 100),
            alignment: Alignment.center,
            height: height / 14,
            decoration:  BoxDecoration(
                color: Colors.grey.shade100,
                border:  Border.all(color: focusBorderColor, width: 1.0),
                borderRadius:  BorderRadius.circular(8.0)),
            child:  TextFormField(
              key: this.widget.key,
              obscureText: this.widget.obscureText,
              onSaved: this.widget.onSaved,
              validator: this.widget.validator,
              onFieldSubmitted: this.widget.onFieldSubmitted,
              decoration:  InputDecoration(
                  border: InputBorder.none,
                  prefixIcon: Icon(
                    this.widget.icon,
                    size: height/34,
                  ),
                  hintText: this.widget.hintText),
            ),
          )),
        ],
      ),
      padding: EdgeInsets.only(bottom : height / 58),
      margin: EdgeInsets.only(
          top: height / 50, right: width / 20, left: width / 30),
    );
  }
}

现在,如果我使用不同的Container进行密码验证,则可以正常工作。而且,如果我将密钥和控制器传递给boxfeild,那么它将显示

多个小部件使用相同的全局密钥

Container _passwordWidget() {
return Container(

  padding: const EdgeInsets.all(16.0),
  alignment: Alignment.center,
  height: 52.0,
  decoration: BoxDecoration(
      color: Colors.grey.shade100,
      border: Border.all(color: Colors.transparent, width: 0.0),
      borderRadius: BorderRadius.circular(12.0)),
  child: TextFormField(
    key: passKey,
    obscureText: true,
    validator: validatePassword,
    onSaved: (String val) {
      _password = val;
    },
    keyboardType: TextInputType.number,
    style: TextStyle(
      fontSize: 22.0,
      color: Colors.black,
    ),
    decoration:
    InputDecoration.collapsed(hintText: "Password"),
  ),
);

}

1 个答案:

答案 0 :(得分:0)

您以错误的方式声明了密码,请使用最终的Globalkey而不是var