I have a list of objects that are all subtypes of Animal. I cast them all to supertype in the animal list to keep their references in one place. So far so good.
Now, when I render state information about each animal object I would like to use different widgets based on the subtype of each Animal object. When I cast from supertype to subtype, even when I specify the field is dynamic, I get the error.
Type 'type' is not a subtype of type '<subtype>'
It seems that the dart compiler uses the type information from the animalTiles map to enforce that all elements are of type Animal, even if the constructor that I pass the type into takes a dynamic named parameter, which I hoped would be looser.
// ANIMAL LIST
class AnimalList extends StatelessWidget {
final Map<String, Animal> animals;
@override
Widget build(BuildContext context) {
List<Widget> animalTiles = [];
animals.forEach(
(key, setting) => animalTiles.add(
AnimalTile(animal: animal),
),
);
return Column(
children: animalTiles,
);
}
}
// ANIMAL TILE
class AnimalTile extends StatelessWidget {
AnimalTile({
required animal,
}) {
_buildDescription(animal);
}
late dynamic animal;
late Widget description;
Widget _buildDescription(dynamic setting) {
if (animal.type == Animal.CAT) {
Cat cat = animal;
return CatWidget(cat: cat);
} else if (animal.type == Animal.DOG) {
Dog dog = animal;
return DogWidget(dog: dog);
} else if (animal.type == Animal.MOUSE) {
Mouse mouse = animal;
return MouseWidget(mouse: mouse);
} else {
return Container(child: Text(':('));
}
}
@override
Widget build(BuildContext context) {
return(
...
);
}
}
The Dart type system requires that I initialize final fields before the constructor body in an initialization list or assign directly to instance fields in the params list. If I call a helper method in the body of my constructor, that is not considered final so I would not like to use this for an immutable Stateless Widget.
This has to be a somewhat common pattern..I am trying to keep all subtypes in the same list and then use the subtype type to display different widgets. Why does this approach fail and what is a valid way to implement this pattern in Dart?