如何验证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,
);
},
),
答案 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,
),