微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Flutter 中,为什么没有密钥的无状态孩子仍然可以工作?

如何解决在 Flutter 中,为什么没有密钥的无状态孩子仍然可以工作?

我正在通过 this post 学习小部件 key 的颤动概念。我很困惑,即使两个无状态子小部件中没有键,它们仍然可以正确交换位置。为什么?难道 key 不是父母跟踪哪个孩子是哪个孩子的唯一方法吗?(以便它可以交换他们的位置)。请在dartpad

中签出代码

解决方法

在等待更好的答案的同时,我已经知道发生了什么(作为一个新手,我可能是错的):

在无状态情况下,当您交换小部件时,会发生三个事实:(1)两个小部件实例确实改变了小部件树中的位置,但是 (2)相应的元素树保持不变(这是因为每个对应的小部件类型都没有变化)。 (3) 元素树中唯一改变的是元素对小部件的引用(以反映小部件树中的顺序变化)。由于无状态小部件都是通过自身信息(无外部状态)更新屏幕,这使得交换正确显示在屏幕上。

在没有key的statefull的情况下,当你交换widgets时,事情的发生与上述无状态情况相同,即所有三个事实都再次发生。但是为什么屏幕上没有显示交换?这是因为对于有状态的小部件,屏幕更新取决于与元素树中相应元素关联的外部对象(即状态)。因此,即使小部件实例交换了位置(蓝色,红色 --> 红色,蓝色),flutter 仍然将它们绘制为(蓝色,红色),因为这是元素树中的顺序(永远不会改变)。

在 stateful with key 的情况下,只有三个中的第一个事实发生。其他两个不再是真的。这里发生的事情是元素树确实根据小部件树的变化而变化。它通过匹配两侧的键和类型来实现这一点。此后,交换在屏幕上正确显示,因为元素确实从(蓝色,红色)变为(红色,蓝色)。请记住,这里的老大是元素树,而不是小部件树。小部件树只是一组配置,元素树是负责在屏幕上绘画的家伙。

还有一个谜题留给我。在没有键的有状态情况下,每次交换发生时,Flutter 都会调用状态对象的 build 方法。但是对于一个键,build 从未被调用过。为什么?我猜这是因为元素树的引用发生了变化。即,每次引用更改时,flutter 调用 build 以重建相应小部件的状态。另一方面,如果有一个键,引用永远不会改变。所以不需要flutter重建状态。

期待有人能证实我的理解。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。