Extending from FormField in a Stateful Widget
I have a Stateful widget with properties and functions. I would like to extend the widget from FormField, because I need to validate some user input on the widget.
It seems that it is not possible to extend from multiple classes (StatefulWidget and FormField).
If I try to create a normal class that extends from FormField:
class CustomInput extends FormField<bool> {
final Widget label;
final void Function(bool?) onChanged;
userClicked() {
print('User clicked');
}
CustomInput({
required this.label,
required this.onChanged,
FormFieldValidator<bool>? validator,
}) : super(
validator: validator,
builder: (field) {
return Column(
children: [
TextButton(
onPressed: () => userClicked(), //<-- The instance member 'userClicked' can't be accessed in an initializer.
child: Text('Call internal function'),
),
... then I cannot access internal methods because of the 'The instance member 'userClicked' can't be accessed in an initializer.' error.
So how do you create a widget that extends from FormField to use the validator
, onChanged
, onSaved
etc., but at the same time have internal logic that can be accessed normally from the widget tree?
Instead of extending FormField, the solution was to return a FormField from the StatefulWidget. In this example the validation content is a string array, but it can of course be whatever:
class CustomInput extends StatefulWidget {
final String? Function(List<String>)? validator;
final Function(List<String>)? onChanged;
const CustomInput({this.onChanged, this.validator, Key? key}) : super(key: key);
@override
State<CustomInput> createState() => _CustomInputState();
}
class _CustomInputState extends State<CustomInput> {
@override
void initState() {
super.initState();
}
userClicked() {
print('User clicked');
}
@override
Widget build(BuildContext context) {
return FormField(validator: ((value) {
if (widget.validator != null) {
return widget.validator!(widget.imagePaths);
}
return null;
}), builder: (FormFieldState<List<String>> state) {
return Column(
children: [
TextButton(
onPressed: () => userClicked(), //<-- The instance member 'userClicked' can't be accessed in an initializer.
child: Text('Call internal function'),
),
]
);
});
}
}