I'm trying to add an optional function to my widget:
final void Function(List<TList>)? onConfirm;
Getting this error:
"Error: Expected a value of type '((List) => void)?', but got one of type '(List) => void'
On the specified line of my widget:
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:multi_select_flutter/chip_display/multi_select_chip_display.dart';
import 'package:multi_select_flutter/util/multi_select_item.dart';
import 'package:new_day_flutter/generated/l10n.dart';
import 'package:new_day_flutter/presentation/common/widgets/form_fields/multiselect_dialog/fb_multiselect_dialog_field.dart';
import 'package:new_day_flutter/presentation/theme/palette.dart';
class BlMultiselectField<TList> extends StatefulWidget {
const BlMultiselectField({
Key? key,
required this.name,
required this.options,
required this.labelText,
this.onConfirm,
this.hasFocus = false,
this.initialValue = const [],
this.dialogHeight,
this.globalKey,
this.onFocusChange,
}) : super(key: key);
final GlobalKey<FormFieldState>? globalKey;
final List<MultiSelectItem<TList>> options;
final List<TList> initialValue;
final double? dialogHeight;
final String name;
final void Function(bool)? onFocusChange;
final bool hasFocus;
final String labelText;
final void Function(List<TList>)? onConfirm;
@override
_BlMultiselectFieldState createState() => _BlMultiselectFieldState();
}
class _BlMultiselectFieldState<TList> extends State<BlMultiselectField<TList>> {
@override
Widget build(BuildContext context) {
return FocusScope(
child: FocusScope(
child: Focus(
onFocusChange: (isFocused) {
if (widget.onFocusChange != null) {
widget.onFocusChange!(isFocused);
}
},
child: FormBuilderField<List<TList>>(
name: widget.name,
initialValue: widget.initialValue,
builder: (FormFieldState<List<TList>> field) {
String labelText = (field.value ?? []).isNotEmpty
? S.of(context).selectedCount(field.value!.length)
: widget.labelText;
return BlMultiSelectDialogField<TList>(
key: GlobalKey(),
chipDisplay: MultiSelectChipDisplay.none(),
searchable: true,
initialValue: widget.initialValue,
items: widget.options,
selectedValues: field.value ?? [],
title: Text(widget.labelText),
selectedColor: bluelabBlue,
dialogHeight: widget.dialogHeight,
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(color: bluelabBlue),
),
),
labelText: Text(
labelText,
style: const TextStyle(color: bluelabBlue),
),
labelIcon: const Icon(
Icons.arrow_drop_down,
color: bluelabBlue,
size: 24,
),
onConfirm: (value) {
widget.onConfirm?.call(value); //************* HERE *********
field.didChange(value);
},
onCancel: (context, value) {
setState(() {
});
Navigator.pop(context);
},
);
}))));
}
}
Using the widget like so:
BlMultiselectField<String>(
globalKey: _filterDeviceGlobalKey,
labelText: S.of(context).selectDevice,
onConfirm: (x) {
setState(() {});
},
name: 'devices',
initialValue:
widget.selectedDeviceIdentifiers.map((e) => e.key).toList(),
options: devices
.map((e) => MultiSelectItem<String>(e.key, e.value))
.toList(),
dialogHeight: 200,
)
UPDATE It works when I change it to this:
final void Function(List<dynamic>)? onConfirm;
Don't know why it was not handling the generic though.
CodePudding user response:
I think you should do this instead:
final void Function(List<TList>?) onConfirm;
CodePudding user response:
This
_BlMultiselectFieldState createState() => _BlMultiselectFieldState();
should really be:
_BlMultiselectFieldState<TList> createState() => _BlMultiselectFieldState<TList>();
Otherwise the TList
of your state class will always be dynamic
and not match the TList
type of your widget. Which is a problem when you use a function that has TList
in it's signature.