I am implementing an infinite scroll list for a home feed in a Flutter app. The list contains different items that are rendered with different widgets. I use the freezed package to create domain models that I initialize with the response from an API. Now I need some way to differentiate the models to render the correct widget. I decided to create a general HomeFeedItem widget, that does the rendering.
class HomeFeedItem extends StatelessWidget {
final dynamic item;
const HomeFeedItem({Key? key, required this.item}) : super(key: key);
@override
Widget build(BuildContext context) {
final Widget widget;
switch (item.runtimeType) {
case TodayDivider:
widget = const TodayDivider();
case DateDivider:
widget = DateDivider(date: item.date);
case CheckinCTA:
widget = const CheckinCTA();
case EntryPreview:
widget = EntryPreview(
id: item.id,
title: item.title,
summary: item.summary,
);
default:
widget = const Text('Unknown item type');
}
return Column(
children: [
widget,
const SizedBox(height: 24),
],
);
}
}
The issue is that for example of EntryPreview
the runtimeType
is _$EntryPreviewImpl
, which is private. So this approach fails and every item is Text("Unknown item type")
I could add a getter to each model that returns a type. But I was wondering if there isn’t a better way to pattern match the type of a freezed class.
2
Answers
Maybe. you can use like this
Doing:
uses a constant pattern that compares the
Type
object returned byitem.runtimeType
for equality. Equality forType
objects is object identity; they compare equal only to themselves regardless of relationships between types.You instead should use a variable pattern that matches
item
and notitem.runtimeType
: