有关构建Flutter UI的众多问题归结为错误的BuildContext
(例如显示SnackBar
)。答案通常是使用Builder
或使用GlobalKey
。两者都有效,但是我注意到GlobalKey的文档指出:
全局密钥相对昂贵。如果不需要上面列出的任何功能,请考虑改用
Key
,ValueKey
,ObjectKey
或UniqueKey
。
所指的功能是唯一的标识和子树重新成对。在这种情况下使用GlobalKey
的“相对费用”是否足以代替使用Builder
?
答案 0 :(得分:5)
我们倾向于避免使用GlobalKey
的真正原因与性能无关。与此有关的是,它会打乱一些图案。
按定义,小部件不应能够访问其他小部件的具体信息(例如它们的大小或位置)。并且GlobalKey
授予访问此类信息的能力;允许人们做反模式的东西。
认为GlobalKey
是弹出 Flutter反应层的平均值。
使用GlobalKey
诱使人们做什么的一些示例:
GlobalKey
。用作不提升状态的手段。使得小部件之间的交互变得难以预测,因为这种关系不再是单面的(父母->孩子变成了双向关系)GlobalKey
计算布局的大小。然后使用此信息触发重新渲染。相反,这是RenderObject
的角色,不应在小部件中完成。这使得布局难以维护 Builder
不会破坏这些模式。因此,根据定义,Builder
什么都不做。这只是使用其他BuildContext
的一种巧妙方法。
这通常意味着,如果您可以使用Builder
而不是GlobalKey
解决布局问题,那么您将走上可维护布局的正确轨道。
那么什么时候使用GlobalKey
?
好吧,如果可以,永远不会。尝试改用context.ancestorStateOfType
或context.inheritWidgetOfExtactType
之类的东西。您可能还需要考虑为特定布局创建自定义RenderObject
。如果您需要父母/子女之间的关系,也可以将RenderObject
与parentData
结合使用
这可能更复杂。它可能消耗比您想要的更多的时间。否则您可能陷入使用当前API难以实现的极端情况。
在这种情况下,只要您知道潜在的后果,就可以使用GlobalKey
。
答案 1 :(得分:4)
GlobalKey
昂贵很可能与您可能需要很多钥匙的情况有关,例如ListView
的孩子。
我怀疑GlobalKey
的成本SnackBar
会很重要。您不太可能创建许多此类文件。