复选框表单验证

时间:2018-11-26 11:16:20

标签: flutter

如何验证Flutter Form中的复选框?其他所有验证都可以正常工作,但是该复选框没有显示错误。 这是我的代码:

FormField(
  validator: (value) {
    if (value == false) {
      return 'Required.';
    }
  },
  builder: (FormFieldState<dynamic> field) {
    return CheckboxListTile(
      value: checkboxValue,
      onChanged: (val) {
        if (checkboxValue == false) {
          setState(() {
            checkboxValue = true;
          });
        } else if (checkboxValue == true) {
          setState(() {
            checkboxValue = false;
          });
        }
      },
      title: new Text(
        'I agree.',
        style: TextStyle(fontSize: 14.0),
      ),
      controlAffinity: ListTileControlAffinity.leading,
      activeColor: Colors.green,
    );
  },
),

4 个答案:

答案 0 :(得分:5)

一个更清洁的解决方案是创建一个扩展FormField<bool>

的类。

这是我的完成方式:

class CheckboxFormField extends FormField<bool> {
  CheckboxFormField(
      {Widget title,
      @required BuildContext context,
      FormFieldSetter<bool> onSaved,
      FormFieldValidator<bool> validator,
      bool initialValue = false,
      bool autovalidate = false})
      : super(
            onSaved: onSaved,
            validator: validator,
            initialValue: initialValue,
            autovalidate: autovalidate,
            builder: (FormFieldState<bool> state) {
              return CheckboxListTile(
                dense: state.hasError,
                title: title,
                value: state.value,
                onChanged: state.didChange,
                subtitle: state.hasError
                    ? Text(
                        state.errorText,
                        style: TextStyle(color: Theme.of(context).errorColor),
                      )
                    : null,
                controlAffinity: ListTileControlAffinity.leading,
              );
            });
}

答案 1 :(得分:3)

如果要将复选框直接放在“表单”小部件树中,则可以使用下面随FormField小部件提供的解决方案。我没有使用ListTile,而是使用行和列,因为我的表单需要不同的布局。

FormField<bool>(
  builder: (state) {
    return Column(
      children: <Widget>[
        Row(
          children: <Widget>[
            Checkbox(
              value: checkboxValue,
              onChanged: (value) {
                setState(() {
//save checkbox value to variable that store terms and notify form that state changed
                  checkboxValue = value;
                  state.didChange(value);
                });
              }),
            Text('I accept terms'),
          ],
        ),
//display error in matching theme
        Text(
          state.errorText ?? '',
          style: TextStyle(
            color: Theme.of(context).errorColor,
          ),
        )
      ],
    );
  },
//output from validation will be displayed in state.errorText (above)
  validator: (value) {
    if (!checkboxValue) {
      return 'You need to accept terms';
    } else {
      return null;
    }
  },
),

答案 2 :(得分:1)

您可以尝试这样的事情:

CheckboxListTile(
  value: checkboxValue,
  onChanged: (val) {
    if (checkboxValue == false) {
      setState(() {
        checkboxValue = true;
      });
    } else if (checkboxValue == true) {
      setState(() {
        checkboxValue = false;
      });
    }
  },
  subtitle: !checkboxValue
      ? Text(
          'Required.',
          style: TextStyle(color: Colors.red),
        )
      : null,
  title: new Text(
    'I agree.',
    style: TextStyle(fontSize: 14.0),
  ),
  controlAffinity: ListTileControlAffinity.leading,
  activeColor: Colors.green,
);

答案 3 :(得分:0)

上面的答案是正确的,但是,如果您想显示与TextFormField小部件错误消息的默认布局更一致的错误消息,则将Text小部件包装在Padding小部件中,并为其指定十六进制颜色#e53935。

注意:您可能需要调整左侧填充以适合CheckboxListTile小部件,该小部件也包装在Padding小部件中。

检查以下代码:

    bool _termsChecked = false;
    CheckboxListTile(
              activeColor: Theme.of(context).accentColor,
              title: Text('I agree to'),
              value: _termsChecked,
              onChanged: (bool value) => setState(() => _termsChecked = value),
              subtitle: !_termsChecked
                ? Padding(
                    padding: EdgeInsets.fromLTRB(12.0, 0, 0, 0), 
                    child: Text('Required field', style: TextStyle(color: Color(0xFFe53935), fontSize: 12),),)
                : null,
            ),