'Why does Dart expect a value of type dynamic instead of T in a generic class [duplicate]
So I'm working on a flutter app and created a generic dropdownbutton class that I want to fill with objects from a database. The dropdownbutton takes a list of these objects, a function to get the display values of them and then shows these display values in the dropdownmenu. Here is the generic dropdownbutton class:
class GenericDropdownButton<T> extends StatefulWidget {
T? _selectedValue;
final List<T> _values;
final String Function(T value) _displayValueGetter;
GenericDropdownButton(this._values, this._displayValueGetter, {Key? key})
: super(key: key);
@override
State<GenericDropdownButton> createState() => _GenericDropdownButtonState();
}
class _GenericDropdownButtonState<T> extends State<GenericDropdownButton<T>> {
@override
Widget build(BuildContext context) {
return DropdownButton<T>(
value: widget._selectedValue,
items: widget._values.map((T value) {
return DropdownMenuItem<T>(
value: value,
child: Text(widget._displayValueGetter(value)),
//child: Text(value.toString()),
);
}).toList(),
onChanged: (T? newValue) {
setState(() {
widget._selectedValue = newValue;
});
},
);
}
}
I created a simple class for demonstration purposes to pass to the dropdownbutton:
class TestClass {
int id;
String name;
TestClass(this.id, this.name);
}
And I instantiate a dropdownbutton like this:
class TestPage extends StatefulWidget {
const TestPage({Key? key}) : super(key: key);
@override
State<TestPage> createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Generic dropdown button test'),
),
body: Column(mainAxisSize: MainAxisSize.max, children: <Widget>[
GenericDropdownButton<TestClass>(
<TestClass>[TestClass(1, 'One'), TestClass(2, 'Two')],
(TestClass t) => t.name
),
]),
);
}
}
When I execute this, I get the following error:
Expected a value of type '(dynamic) => String', but got one of type '(TestClass$) => String'
Which corresponds to this line:
child: Text(widget._displayValueGetter(value)),
So as far as I understand, dart expects the parameter 'value' to be of type 'dynamic', although it's clearly of type 'T' (in this case of type 'TestClass'), since '_displayValueGetter' is of type 'String Function(T)'. Why does dart expect that and how can I prevent dart from expecting that?
Solution 1:[1]
The type wasn't specified in createState which is why it's choosing to be dynamic.
Specify it like so:
@override
State<GenericDropdownButton<T>> createState() => _GenericDropdownButtonState<T>();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Josteve |
