Reputation: 2771
Below is a code mock-up for generic StatefulWidget that uses a FutureBuilder. I get the following error when FutureBuilder instantiates:
type '(User) => Future<List<User>>' is not a subtype of type '(dynamic) => Future<List<dynamic>>'
I suspect the error is the compiler wouldn't know that T
and U
are the same, so U
is declared as dynamic while T
as User
? How would I change this code so the type used for the generic in the StatefulWidget is passed to State widget?
Widget build(BuildContext context) => TestWidget<User>();
class TestWidget<T> extends StatefulWidget {
final Future<List<T>> Function(T) myFunc = (_) => Future<List<T>>(null);
@override
_TestState<T> createState() => _TestState<T>();
}
class _TestState<U> extends State<TestWidget> {
@override
Widget build(BuildContext context) {
return FutureBuilder<List<U>>(
future: widget.myFunc(null),
builder: (context, snapshot) {
return Container();
});
}
}
Upvotes: 1
Views: 1143
Reputation: 76
You can see how FutureBuilder solved this issue. Instead of writing a return type of _TestState<T>
for the createState()
method, you would write State<TestWidget<T>>
.
State<TestWidget<T>> createState() => _TestState<T>();
Upvotes: 2
Reputation: 2771
I ended up effectively creating a second build()
function in the StatefulWidget class that uses the T
generic. It gets called from the build()
in the State class. That way the State class doesn't care about the generics. I would have switched to a StatelessWidget with managed states, but I need to use AutomaticKeepAliveClientMixin, so had to stick with a StatefulWidget. My actual State class uses the mixin and has a bit more going on.
class TestWidget<T> extends StatefulWidget {
final Future<List<T>> Function(T) myFunc = (_) => Future<List<T>>(null);
Widget build(BuildContext context) {
return FutureBuilder<List<T>>(
future: myFunc(null),
builder: (context, snapshot) {
return Container();
});
}
@override
_TestState createState() => _TestState();
}
class _TestState extends State<TestWidget> {
@override
Widget build(BuildContext context) {
return widget.build(context);
}
}
Upvotes: 0