【问题标题】:How to take correct home address from user?如何从用户那里获取正确的家庭地址?
【发布时间】:2020-10-02 04:12:38
【问题描述】:

我正在使用 Flutter 构建一个应用程序,我正在向用户询问他们的地址。目前我正在使用普通表单字段来获取城市、邮政编码、州和国家/地区等数据,因此有些用户只需在字段中输入任何甚至没有意义的内容,例如州名称不属于该国家/地区列表和相同带有邮政编码和城市。

我想限制用户输入正确的数据。例如,如果有人输入 Country USA,则只能输入位于美国的州。我不知道该怎么做,有没有可用的包或api?

【问题讨论】:

    标签: flutter


    【解决方案1】:

    使用 Flutter Forms 验证。看起来很冗长,但 Flutter 就是这样做的。

    将您的字段包装在 Form() 中。对于每一个,您将拥有一个 onChanged 函数、一个 onSaved 函数(可能),然后为每个字段添加一个验证器函数。这是重要的部分。如果数据没有问题,验证器应该返回 null。如果出现问题,它应该返回一个带有错误描述的字符串。

    这是一个太大的代码示例:

    // <-- Add this widget. (Don't forget to close it!)
            autovalidate: _autovalidate, // <-- Add this line
            key: _key, // <-- Add this line
            child: Container(
              alignment: Alignment.center,
              child: Column(
                children: <Widget>[
                  _buildEmailField,
                  _buildPasswordField,
                  _buildPasswordConfirmationField,
                  _buildAgreeToTermsField,
                ],
              ),
            ),
          ),
          floatingActionButton: FloatingActionButton(
            child: Icon(Icons.save),
            onPressed: _doRegister,
          ),
        );
      }
    
      Widget get _buildEmailField {
        return TextFormField(
          // TODO 4: Change to a TextFormField
          decoration: InputDecoration(labelText: "Email"),
          // TODO 5: Add onSaved and validator methods
          onSaved: (String val) => _loginObject['email'] = val,
          validator: _validateEmail,
          // TODO 9: Add autofocus
          autofocus: true,
          // TODO 10: Add a focusNode
          focusNode: _emailFocusNode,
        );
      }
    
      Widget get _buildPasswordField {
        return TextFormField(
          // TODO 4: Change to a TextFormField
          decoration: InputDecoration(labelText: "Password"),
          obscureText: true,
          onChanged: (String val) => setState(() => _pass1 = val),
          // TODO 6: Add onSaved and validator methods to the password field
          onSaved: (String val) => _loginObject['password'] = val,
          validator: _validatePassword,
        );
      }
    
      Widget get _buildPasswordConfirmationField {
        return TextFormField(
          // TODO 4: Change to a TextFormField
          decoration: InputDecoration(labelText: "Password (again)"),
          obscureText: true,
          // TODO 7: Validate the password confirmation here
          validator: _validatePasswordConfirmation,
        );
      }
    
      Widget get _buildAgreeToTermsField {
        // TODO 8: Wrap the Column with a FormField<bool>
        return FormField<bool>(
          // 1
          initialValue: _agree,
          builder: (FormFieldState<bool> state) {
            // 2
            return Column(
              children: <Widget>[
                Row(
                  children: <Widget>[
                    Checkbox(
                      // 3
                      value: state.value,
                      onChanged: (bool val) => setState(() {
                        // 4
                        _agree = val;
                        // 5
                        state.didChange(val);
                      }),
                    ),
                    const Text("I agree to the terms."),
                  ],
                ),
                // 6
                state.errorText == null
                    ? Text("")
                    : Text(state.errorText, style: TextStyle(color: Colors.red)),
              ],
            );
          },
          // 7
          validator: (val) => _validateTerms(_agree),
        );
      }
    
      // Valid if we get a well-formed and non-empty email address
      String _validateEmail(String email) {
        // 1
        RegExp regex = RegExp(r'\w+@\w+\.\w+');
        // Add the following line to set focus to the email field
        if (email.isEmpty || !regex.hasMatch(email)) _emailFocusNode.requestFocus();
        // 2
        if (email.isEmpty)
          return 'We need an email address';
        else if (!regex.hasMatch(email))
          // 3
          return "That doesn't look like an email address";
        else
          // 4
          return null;
      }
    
      String _validatePassword(String pass1) {
        RegExp hasUpper = RegExp(r'[A-Z]');
        RegExp hasLower = RegExp(r'[a-z]');
        RegExp hasDigit = RegExp(r'\d');
        RegExp hasPunct = RegExp(r'[_!@#\$&*~-]');
        if (!RegExp(r'.{8,}').hasMatch(pass1))
          return 'Passwords must have at least 8 characters';
        if (!hasUpper.hasMatch(pass1))
          return 'Passwords must have at least one uppercase character';
        if (!hasLower.hasMatch(pass1))
          return 'Passwords must have at least one lowercase character';
        if (!hasDigit.hasMatch(pass1))
          return 'Passwords must have at least one number';
        if (!hasPunct.hasMatch(pass1))
          return 'Passwords need at least one special character like !@#\$&*~-';
        return null;
      }
    
      String _validatePasswordConfirmation(String pass2) {
        return (pass2 == _pass1) ? null : "The two passwords must match";
        // Note that _pass1 is populated when a password is entered
      }
    
      String _validateTerms(bool agree) {
        return agree ? null : "You must agree before proceeding";
        // It's invalid if the user hasn't opted in by checking the box
      }
    
      void _doRegister() {
        // After the first attempt to save, turn on autovalidate to give quicker feedback to the user
        setState(() => _autovalidate = true); // <-- Add this line
        // TODO 3: Add validation and saving here
        if (_key.currentState.validate()) {
          // Commit the field values to their variables
          _key.currentState.save();
          print("""
          The user has registered with an email address of '${_loginObject['email']}' 
          and a password of '${_loginObject['password']}'
          """);
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-24
      • 2016-06-06
      • 1970-01-01
      • 2016-12-26
      • 2013-11-23
      • 2015-11-21
      • 1970-01-01
      相关资源
      最近更新 更多