我应该在我的Flutter小工具上使用什么:值键或键

xu3bshqb  于 2023-03-09  发布在  Flutter
关注(0)|答案(3)|浏览(166)

这周我又遇到了这种情况。
我一直在使用key: ValueKey(*aValue*),但没有特别的原因,考虑到使用key: Key(*aValue*)可能会类似地工作。
任何顶级的原因或东西,为深入了解使用,在任何情况下?

utugiqy6

utugiqy61#

myMillionListOfProduct = [
Product(name:soap, price: 10.00),
Product(name:butter, price: 12.00),
...
];

如果您想手动编写不同Key,这是可以的,但是如果您想 * 动态地 * 创建它,那么就会出现一些问题:
我们可以这样使用Key

products.map(product) => ProductWidget(key: Key(product.name),product: product);

但是Key只接受String,如果有相同名称但价格不同的产品怎么办?dart不高兴地告诉你:“密钥的副本”。
那么为了让dart满意,我们可以使用ValueKey

products.map(product) => ProductWidget(key: ValueKey<Product>(product),product: product);

也许有人在他们的引用中创建了一个差异,并添加到我们的myMillionListOfProduct中。

final someguysoap = Product(name:soap,price:10.00).
myMillionListOfProduct.add(someguysoap);

但是,再次有一个产品具有相同的价值,Product(name: soap, price: 10.00),使用ValueKey将使dart再次不高兴。
那么我们使用ObjectKey来代替。

myMillionListOfProduct = [
Product(name:soap, price: 10.00),
Product(name:butter, price: 12.00),
someguysoap,
...
];

products.map(product) => ProductWidget(key: ObjectKey(product),product: product);

如果这个人用相同的参考再添加1个产品呢?

myMillionListOfProduct = [
Product(name:soap, price: 10.00),
Product(name:butter, price: 12.00),
someguysoap,
someguysoap,
...
];

那么dart会告诉你这些小部件有相同的objectKey.如果你想这样的话,
请改用UniqueKey

jq6vz3qz

jq6vz3qz2#

Key类用于在widget树中唯一标识widget,KeyValueKey子类用于需要基于对象值而不是对象标识本身的键。
一般情况下,当键需要基于对象的值时,建议使用ValueKey,因为ValueKey使用对象的hashCode==方法来确定键。这确保了即使对象本身以不同的属性被重新创建,密钥也保持相同。这对于由于状态更改而需要重建小部件树的情况非常重要,因为使用ValueKey可以确保正确更新相应的小部件。
另一方面,如果键只需要基于对象的标识,那么使用Key就足够了,这通常是在创建一个状态与前一个小部件不同的新小部件时出现的情况。
总之,当键需要基于对象的值时,使用ValueKey;当键只需要基于对象的标识时,使用Key

olhwl3o2

olhwl3o23#

Key是抽象类,不能直接启动,继承key的类很少。

  • LocalKey(另一个扩展Key的抽象类)。你也不能直接初始化它。LocalKey是一个非全局的键。
  • UniqueKey -每次调用构建时,您想要重建小工具时使用的本地键)。
  • ObjectKey -用于基于传递的对象标识项的本地键。它使用标识比较来查看键是否相等。因此,如果在生成之间对象引用相同,则键将相同。如果它们具有不同的引用,则将调用生成方法。
  • ValueKey(本地键,用于根据小部件中的值来标识不同的项,小部件具有类似类型的子项,如列表/行/列)。您可以将item.id作为valueKey或整个项传递。如果子项是有状态小部件,则此操作将变得更加重要。
  • GlobalKey(在整个应用程序中唯一的键)。它不应该在每次构建时重新创建。您不能将同一个GlobalKey与多个小部件一起使用,这会导致冲突。
  • LabeledGlobalKey -具有调试级别的全局密钥。
  • 与ObjectKey相同,但是在全局级别。因此您可以在任何地方访问它。

相关问题