在颤动中检查验证之前验证变为真

validation is becomes true before validation is checked in flutter

我对验证有疑问。我的小部件字段验证在检查之前变为真。当我刚打开此页面时,验证自动变为 true。

我想要在用户输入后进行验证。但是在用户从现场输入内容之前,这种验证正在成为现实。所以有人可以帮助我吗?您的帮助将不胜感激。

这是我试过的代码。

class BspSignupPage extends StatefulWidget {
  static const String routeName = "/bspSignup";

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

class _BspSignupPageState extends State<BspSignupPage>
    with AfterLayoutMixin<BspSignupPage> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  // final TextEditingController _bspPhone = TextEditingController();
  final MaskedTextController _bspPhone =
      new MaskedTextController(mask: '(000)-000-0000');
  final TextEditingController _bspBusinessName = TextEditingController();
  final TextEditingController _bspBusinessLegalAddress =
      TextEditingController();
  final TextEditingController _bspBusinessLicense = TextEditingController();
  final TextEditingController _bspLicenseAuthority = TextEditingController();
  final TextEditingController _bspEstYear = TextEditingController();
  final TextEditingController _bspNumberOfEmployee = TextEditingController();
  final TextEditingController _bspBusinessDetailsComment =
      TextEditingController();
  final TextEditingController _countryCodeController =
      new TextEditingController();

  BSPSignupRepository _bspSignupRepository = new BSPSignupRepository();
  bool bspcheck = false;
  BspSignupCommonModel model = BspSignupCommonModel();
  int radioValue = -1;
  String _alternatephone;
  String _businessname;
  bool addressenabled = false;
  List<dynamic> _type = <dynamic>[];
  Map<String, dynamic> _typeValue;
  String _establishyear;
  String _numberofemployee;
  LocationResult _pickedLocation;
  DateTime selectedDate = DateTime.now();
  bool flexibletime = false;
  DateTime date;
  TimeOfDay time;
  Map<String, dynamic> bspsignupdata = new Map<String, dynamic>();

  @override
  void initState() {
    super.initState();
    print(model);
    _bspNumberOfEmployee.text = "1";
    _bspSignupRepository.getBSTypes().then((businessTypeResponse) {
      print('businessTypeResponse');
      print(businessTypeResponse);
      if (businessTypeResponse['error'] != null) {
      } else {
        setState(() {
          _type = businessTypeResponse['data']['businessTypes'];
        });
      }
    });
    setState(() {
      date = new DateTime.now().add(new Duration(hours: 1));
      time = new TimeOfDay.fromDateTime(date);
    });
  }

  @override
  void afterFirstLayout(BuildContext context) {
    model = ModalRoute.of(context).settings.arguments;
    if (model == null) {
      model = new BspSignupCommonModel();
    } else {
      print('model for edit');
      _setExistingDetails(model);
    }
  }

  void _setExistingDetails(bspModel) {
    _bspBusinessName.text = bspModel.businessLegalName;
    _bspPhone.text = model.businessPhoneNumber;
    _bspEstYear.text = model.businessYear;
    _bspNumberOfEmployee.text = model.numberofEmployees;
    _bspBusinessLegalAddress.text = model.businessLegalAddress;
    _typeValue = model.businessTypes;

  }

  Widget _buildlegalbusinessname() {
    return new TudoTextWidget(
      controller: _bspBusinessName,
      textCapitalization: TextCapitalization.sentences,
      prefixIcon: Icon(Icons.business),
      labelText: AppConstantsValue.appConst['bspSignup']['legalbusinessname']
          ['translation'],
      hintText: AppConstantsValue.appConst['bspSignup']['legalbusinessname']
          ['translation'],
      validator: (val) =>
          Validators.validateRequired(val, "Business legal name"),
      onSaved: (val) {
        _businessname = val;
        bspsignupdata['businessname'] = _businessname;
      },
    );
  }

  Widget _buildalternatephone() {
    return Row(
      children: <Widget>[
        new Expanded(
          child: new TudoTextWidget(
            controller: _countryCodeController,
            enabled: false,
            prefixIcon: Icon(FontAwesomeIcons.globe),
            labelText: "code",
            hintText: "Country Code",
          ),
          flex: 2,
        ),
        new SizedBox(
          width: 10.0,
        ),
        new Expanded(
          child: new TudoNumberWidget(
            controller: _bspPhone,
            validator: Validators().validateMobile,
            labelText: AppConstantsValue.appConst['bspSignup']['alternatephone']
                ['translation'],
            hintText: AppConstantsValue.appConst['bspSignup']['alternatephone']
                ['translation'],
            prefixIcon: Icon(Icons.phone),
            onSaved: (val) {
              _alternatephone = val;
              bspsignupdata['alternatephone'] = _alternatephone;
            },
          ),
          flex: 5,
        ),
      ],
    );
  }

  Widget _buildestablishedyear() {
    return new TudoNumberWidget(
      controller: _bspEstYear,
      prefixIcon: Icon(FontAwesomeIcons.calendar),
      labelText: AppConstantsValue.appConst['bspSignup']['establishedyear']
          ['translation'],
      hintText: AppConstantsValue.appConst['bspSignup']['establishedyear']
          ['translation'],
      validator: Validators().validateestablishedyear,
      maxLength: 4,
      onSaved: (val) {
        _establishyear = val.trim();
        bspsignupdata['establishyear'] = _establishyear;
      },
    );
  }

  Widget _buildnumberofemployees() {
    return new TudoNumberWidget(
      controller: _bspNumberOfEmployee,
      prefixIcon: Icon(Icons.control_point_duplicate),
      labelText: AppConstantsValue.appConst['bspSignup']['numberofemployees']
          ['translation'],
      hintText: AppConstantsValue.appConst['bspSignup']['numberofemployees']
          ['translation'],
      validator: Validators().validatenumberofemployee,
      onSaved: (val) {
        _numberofemployee = val.trim();
        bspsignupdata['numberofemployes'] = _numberofemployee;
      },
    );
  }

  Widget _buildbusinesslegaladdress() {
    return Row(
      children: <Widget>[
        new Expanded(
          child: new TudoTextWidget(
            prefixIcon: Icon(Icons.business),
            labelText: AppConstantsValue.appConst['bspSignup']
                ['businesslegaladdress']['translation'],
            hintText: AppConstantsValue.appConst['bspSignup']
                ['businesslegaladdress']['translation'],
            controller: _bspBusinessLegalAddress,
            enabled: addressenabled,
            validator: (val) =>
                Validators.validateRequired(val, "Business legal name"),
          ),
          flex: 5,
        ),
        new SizedBox(
          width: 10.0,
        ),
        new Expanded(
          child: new FloatingActionButton(
            backgroundColor: colorStyles['primary'],
            child: Icon(
              FontAwesomeIcons.globe,
              color: Colors.white,
            ),
            elevation: 0,
            onPressed: () async {
              LocationResult result = await LocationPicker.pickLocation(
                context,
                "AIzaSyDZZeGlIGUIPs4o8ahJE_yq6pJv3GhbKQ8",
              );
              print("result = $result");
              setState(() {
                _pickedLocation = result;
                addressenabled = !addressenabled;
              });
              // setState(() => _pickedLocation = result);
              _bspBusinessLegalAddress.text = _pickedLocation.address;
              model.businessGeoLocation = new BusinessGeoLocation(
                lat: _pickedLocation.latLng.latitude.toString(),
                lng: _pickedLocation.latLng.longitude.toString(),
              );
            },
          ),
          flex: 2,
        ),
      ],
    );
  }

  Widget _buildbusinesstype() {
    return FormBuilder(
      autovalidate: true,
      child: FormBuilderCustomField(
          attribute: "Business type",
          validators: [FormBuilderValidators.required()],
          formField: FormField(
            builder: (FormFieldState<dynamic> field) {
              return InputDecorator(
                decoration: InputDecoration(
                  prefixIcon: Icon(Icons.perm_identity),
                  labelText: _type == []
                      ? 'Select Personal Identification type'
                      : 'Business type',
                  hintText: "Select Personal Identification type",
                  errorText: field.errorText,
                ),
                isEmpty: _typeValue == [],
                child: new DropdownButtonHideUnderline(
                  child: new DropdownButton(
                    // isExpanded: true,
                    hint: Text("Select Personal Identification type"),
                    value: _typeValue,
                    isDense: true,
                    onChanged: (dynamic newValue) {
                      print('newValue');
                      print(newValue);
                      setState(() {
                        _typeValue = newValue;
                        field.didChange(newValue);
                      });
                    },
                    items: _type.map(
                      (dynamic value) {
                        return new DropdownMenuItem(
                          value: value,
                          child: new Text(value['name']),
                        );
                      },
                    ).toList(),
                  ),
                ),
              );
            },
          )),
    );
  }

  Widget _buildlegalbusinesscheck() {
    return TudoConditionWidget(
      text: AppConstantsValue.appConst['bspSignup']['legalbusinesscheck']
          ['translation'],
      errortext: AppConstantsValue.appConst['bspSignup']['errortext']
          ['translation'],
    );
  }

  Widget content(BuildContext context, BspSignupViewModel bspSignupVm) {
    final appBar = AppBar(
      title: Text("BSP Signup"),
      leading: IconButton(
        icon: Icon(Icons.arrow_back_ios),
        onPressed: () {
          NavigationHelper.navigatetoBack(context);
        },
      ),
      centerTitle: true,
    );

    final bottomNavigationBar = Container(
      color: Colors.transparent,
      height: 56,

      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          new FlatButton.icon(
            icon: Icon(Icons.close),
            label: Text('Clear'),
            color: Colors.redAccent,
            textColor: Colors.black,
            padding: EdgeInsets.symmetric(vertical: 10, horizontal: 30),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(7),
            ),
            onPressed: () {
              _formKey.currentState.reset();
              _bspPhone.clear();
              _bspBusinessName.clear();
              _bspBusinessLicense.clear();
              _bspLicenseAuthority.clear();
              _bspEstYear.clear();
              _bspNumberOfEmployee.clear();
              _bspBusinessDetailsComment.clear();
              _bspBusinessLegalAddress.clear();
            },
          ),
          new FlatButton.icon(
            icon: Icon(FontAwesomeIcons.arrowCircleRight),
            label: Text('Next'),
            color: colorStyles["primary"],
            textColor: Colors.white,
            padding: EdgeInsets.symmetric(vertical: 10, horizontal: 30),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(7),
            ),
            onPressed: () async {
              if (_formKey.currentState.validate()) {
                model.businessLegalName = _bspBusinessName.text;
                model.businessPhoneNumber = _bspPhone.text;
                model.businessYear = _bspEstYear.text;
                model.numberofEmployees = _bspNumberOfEmployee.text;
                model.businessType = _typeValue['id'];
                model.businessLegalAddress = _bspBusinessLegalAddress.text;
                model.businessTypes = _typeValue;
                print('model');
                print(model.licensed);
                if (_typeValue['name'].toLowerCase() ==
                    "Licensed / Registered".toLowerCase()) {
                  model.isLicensed = true;
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => BspLicensedSignupPage(
                        bspSignupCommonModel: model,
                      ),
                    ),
                  );
                } else {
                  model.isLicensed = false;
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => BspUnlicensedSignupPage(
                        bspSignupCommonModel: model,
                      ),
                    ),
                  );
                }
              }
            },
          ),
        ],
      ),
    );
    return Scaffold(
      appBar: appBar,
      bottomNavigationBar: bottomNavigationBar,
      body: Container(
        height: double.infinity,
        width: double.infinity,
        child: Form(
          autovalidate: true,
          key: _formKey,
          child: Stack(
            children: <Widget>[
              // Background(),
              SingleChildScrollView(
                padding: const EdgeInsets.all(30.0),
                child: new Container(
                  child: new Column(
                    mainAxisAlignment: MainAxisAlignment.start,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      _buildlegalbusinessname(),
                      _buildalternatephone(),
                      _buildestablishedyear(),
                      _buildnumberofemployees(),
                      SizedBox(
                        height: 5,
                      ),
                      _buildbusinesslegaladdress(),
                      _buildbusinesstype(),
                      _buildlegalbusinesscheck(),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return new StoreConnector<AppState, BspSignupViewModel>(
      converter: (Store<AppState> store) => BspSignupViewModel.fromStore(store),
      onInit: (Store<AppState> store) {
        _countryCodeController.text =
            store.state.auth.loginUser.user.country.isdCode;
      },
      builder: (BuildContext context, BspSignupViewModel bspSignupVm) =>
          content(context, bspSignupVm),
    );
  }
}

您的小部件字段验证在检查之前变为真,因为您已将静态标志设置为“自动验证”以解决此问题,您必须为此管理标志变量

示例:-

bool _autoValidate = false;


Form(
      key: _formKey,
      autovalidate: _autoValidate,
      child: Container(child:Text("")));

并在第一次验证表单时更改标志值

void _buttonClicked(BuildContext context) {
  setState(() {
    _autoValidate = true;
    });
  }

更新:-

autovalidate 已从 Flutter v1.19 中弃用

autovalidate 替换为 autovalidateMode。autovalidateMode 可以具有以下 3 个值之一:

autovalidateMode: AutovalidateMode.disabled: 不会发生自动验证。

autovalidateMode: AutovalidateMode.always: 用于自动验证 FormField,即使没有用户交互。

autovalidateMode: AutovalidateMode.onUserInteraction: 用于仅在每次用户交互后自动验证 FormField。