我有一个对象列表,这些对象都是动物的子类型。我将它们全部转换为动物列表中的supertype,以便将它们的引用保存在一个位置。到现在为止,一直都还不错。
现在,当我呈现每个动物对象的状态信息时,我希望根据每个动物对象的子类型使用不同的小部件。当我从超类型转换为子类型时,即使我指定字段是动态的,也会出现错误。
Type 'type' is not a subtype of type '<subtype>'
看来,dart编译器使用的类型信息,从动画Tiles映射强制所有元素的类型是动物,即使我传递到的类型的构造函数采取了一个动态命名参数,我希望这将是松散的。
// 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(
...
);
}
}
Dart类型系统要求我在初始化列表中的构造函数体之前初始化最终字段,或者直接分配给参数列表中的实例字段。如果我在构造函数的主体中调用一个辅助方法,那就不被认为是最终的,所以我不想将其用于不可变的无状态小部件。
这一定是一种常见的模式。。我试图将所有子类型保持在同一个列表中,然后使用子类型显示不同的小部件。为什么这种方法失败了?在Dart中实现这种模式的有效方法是什么?
Flatter Cookbook有一个创建不同子类型项目列表的示例。然而,我发现自己在重复我希望基类可以使用的数据字段。因为,如果我对抽象动物类使用extends代替实现(即接口上的继承),我会得到一个异常,表明Dart正在查看基类的方法,而不是子类中被重写的方法。这不是保持代码干燥的最佳解决方案,但它确实有效。
不幸的是,这意味着我没有一个解决方案,使我能够将我的许多动物使用的数据字段保留在一个类中,但是我发布这个来演示一个有效的模式。
更新:
您还可以跨子类型重用数据字段,同时使用extends(继承)和implements(接口)确保调用的方法是子类型重写的方法。
这是我的解决方案,请胜过我:
// Base Class
abstract class AnimalBase {
AnimalBase({
required this.height,
required this.weight,
required this.name,
required this.genus,
required this.species,
});
final int height;
final double weight;
final String name;
final String genus;
final String species;
static const CAT = 0;
static const DOG = 1;
static const MOUSE = 2;
static AnimalFactory(Map<String, dynamic> json, int type) {
// IN MY CASE I PASS THE TYPE TO A FACTORY
switch (type) {
case CAT:
return Cat.fromJson(json);
case DOG:
return Dog.fromJson(json);
case MOUSE:
return Mouse.fromJson(json);
default:
return null;
}
}
}
// Interface Class
abstract class Animal; {
Widget buildTile();
Widget description();
}
// Example SubType
class Dog extends AnimalBase with Animal {
Dog({
required height,
required weight,
required name,
required genus,
required species,
}) : super(height: height, weight: weight, name: name, genus: genus, species: species);
@override
Dog.fromJson(Map<String, dynamic> json)
throw new UnimplementedError();
}
Map<String, dynamic> toJson() {
throw new UnimplementedError();
}
@override
Widget buildTile() {
return DogTile(dog: this);
}
@override
Widget description() {
return DogDescription(dog: this);
}
}
class AnimalList extends StatelessWidget {
AnimalList({
Key? key,
required this.animals,
}) : super(key: key);
final Map<String, Animal> animals;
@override
Widget build(BuildContext context) {
List<Widget> animalTiles = [];
animals.forEach(
(key, animal) => animalTiles.add(
AnimalTile(animal: animal),
),
);
return CustomScrollView(
shrinkWrap: true,
slivers: [
SliverToBoxAdapter(
child: Column(
children: ...animalTiles.map(animal => animal.buildTile()).toList(),
),
),
SliverFillRemaining(
hasScrollBody: false,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Divider(
color: Colors.black54,
height: 18,
thickness: 4,
indent: 20,
endIndent: 20,
),
],
),
),
],
);
}
}
我希望我有一个只需要一个关键字(extends或implements)的解决方案,但这是我最好的解决方案:)
我正在使用Flutter和Cloud FiRecovery构建一个Instagram克隆,我正在尝试像这样构建数据库: 收藏(“时间线”) 实际上看起来像这样: 阅读项目标题,例如,很容易。我可以渲染一个Listview.builder并使用: 但是我如何遍历每个项目的评论子集合?我尝试了嵌套的Listview和this,但我无法访问elementAt(index)的子集合: 或者有没有更好的方法
是否可以在java中并行地迭代一个集合。我正在中寻找类似C#的东西-命名空间
问题内容: 我正在研究一个难题,其中涉及分析所有大小的k个子集,并找出哪个子集是最佳的。我写了一个解决方案,当子集的数量很少时可以使用,但是对于较大的问题,它用尽了内存。现在,我正在尝试将用python编写的迭代函数转换为java,以便我可以在创建每个子集时对其进行分析,并仅获取代表其优化程度的值,而不是整个集的值,以便不会耗尽记忆。这是我到目前为止的内容,即使很小的问题也似乎还没有解决: 有人可
出身背景我有数字1到20(黑色背景上的白色数字),可以出现在屏幕上,我希望识别这些数字。由于它们不能简单地复制粘贴,我将比较屏幕上数字的白色像素位置与所有20个数字的白色像素位置列表。然而,每个数字可以有大量的像素,并且可能不需要比较所有这些像素来识别该数字。因此,我希望尽可能少地进行比较。 算法问题:我有多个集合,其中的元素在每个集合中是唯一的,但在所有集合中可能不是唯一的。如何找到每个集合的最
问题内容: 在Java中为集合的集合设计一个迭代器。迭代器应隐藏嵌套,使您可以迭代属于所有集合的所有元素,就像使用单个集合一样 问题答案: 这是一个可能的实现。请注意,我没有执行remove():
有没有一种方法我可以用某种方式迭代光标我可以暂停它,然后再继续?MongodbCursor保存最后访问的项目?我只知道foreach迭代,但是否有一些像这样的迭代? 如果有类似的东西存在,我可以保存查询的最后一个项目。提前致谢