Reputation: 1020
I have the ProjectModel
class which implements IIdentified
class. But during runtime, I get an error that ProjectModel
is not a sub type of IIdentified
although it implements it. I have also tried to use extend
instead of implements
in ProjectModel
but that didn't help either. How can I work with interfaces in Dart Flutter so that a Widget can have a generic type that fullfills a certain interface or contract?
Parent class IIdentified
I use like an interface:
abstract class IIdentified {
String id;
String name;
}
Sub class implementing (also tried extending) parent class IIdentified
:
class ProjectModel implements IIdentified {
String id;
DateTime created;
DateTime updated;
bool hasMileage;
bool hasAllowance;
bool hasTravelTime;
String name;
String description;
DateTime startDate;
DateTime endDate;
DateTime completed;
double estimatedTime;
double absentTime;
double presentTime;
Status status;
String companyId;
String customerId;
ProjectModel(
{this.id,
this.created,
this.updated,
this.hasMileage,
this.hasAllowance,
this.hasTravelTime,
this.name,
this.description,
this.startDate,
this.endDate,
this.completed,
this.estimatedTime,
this.absentTime,
this.presentTime,
this.status,
this.companyId,
this.customerId});
I get the following error that the ProjectModel
parameter in a function I'm trying to pass, does not count as being an IIdentified
:
The following _TypeError was thrown building LoaderDropdownButton<ProjectModel>(dirty, dependencies: [MediaQuery], state: LoaderDropdownButtonState<IIdentified>#f2031):
type '(ProjectModel) => void' is not a subtype of type '(IIdentified) => void'
The generic widget only accepting type T extends IIdentified
:
class LoaderDropdownButtonState<T extends IIdentified> extends State<LoaderDropdownButton<T>> {
double displayWidth;
double displayHeight;
@override
void initState() {
init();
super.initState();
}
@override
Widget build(BuildContext context) {
setDisplayDimensions();
return Container(
padding: EdgeInsets.only(left: 25),
color: widget.enableSelect ? themeConfig.dropButtonBg : themeConfig.dropButtonDisabledBg,
child: Theme(
data: ThemeData(canvasColor: Color(0xFFC5C5C5)),
child: DropdownButtonHideUnderline(
child: new DropdownButton<T>(
hint: Row(
children: <Widget>[
Expanded(
flex: 10,
child: Container(
alignment: Alignment.center,
margin: EdgeInsets.only(top: 2),
child: Text(
widget.text,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: widget.enableSelect
? themeConfig.dropButtonFg
: themeConfig.dropButtonDisabledFg,
fontSize: displayWidth * 0.045,
),
),
),
),
Flexible(
flex: 2,
child: Container(
margin: EdgeInsets.only(top: 5),
child: Icon(
Icons.keyboard_arrow_down,
color: widget.enableSelect
? themeConfig.dropButtonFg
: themeConfig.dropButtonDisabledFg,
),
),
)
],
),
iconSize: 0,
isExpanded: true,
items: buildItems(),
onChanged: widget.onChange),
),
),
);
}
void init() {
displayWidth = 1;
displayHeight = 1;
}
setDisplayDimensions() {
if (displayWidth == 1) displayWidth = MediaQuery.of(context).size.width;
if (displayHeight == 1) displayHeight = MediaQuery.of(context).size.height;
}
List<DropdownMenuItem<T>> buildItems() {
return widget.data.map((dataItem) {
return DropdownMenuItem<T>(
value: dataItem,
child: Text(dataItem.name),
);
}).toList();
}
}
Why doesn't ProjectModel
pass as an IIdentified
when it implements/extends it? How do you work with interfaces/contracts in generic widgets?
Thanks!
Upvotes: 3
Views: 1003
Reputation: 31209
I get the following error that the ProjectModel parameter in a function I'm trying to pass, does not count as being an IIdentified.
I don't think you actually pasted that function but I can properly still guess what happen. The problem is that you have made a function with the signature:
(ProjectModel) => void
And want to use it as argument where it takes a (IIdentified) => void
. This is a common problem when we are talking inheritance and method arguments since it can seem a little backward.
But, the problem is that if you have a method which can take a IIdentified
as argument, it should be able to take all kind of IIdentified
and not just a specific kind of IIdentified
. You cannot just give a function which can handle ProjectModel
and assume it would be able to handle some other subclass of IIdentified
.
If we are instead was going to have the following:
() => ProjectModel
Then this would be a valid subtype of () => IIdentified
since we are allowed to return a more specific kind of IIdentified
.
Upvotes: 2