我有一个基于枚举值返回两个有状态小部件之一的方法。但是,即使我可以通过调试器看到返回了“正确”的小部件,UI也只显示了第一个被渲染的小部件。看来状态对象以某种方式在窗口小部件的不同实例之间共享,或者我丢失了一些东西。
Widget _buildInfoCard(LoginStatus status) {
switch(status) {
case LoginStatus.LOGIN_FAILED:
return InfoCard("Login failed, please check your username and password.");
default:
return InfoCard("Please login with your username and password");
}
}
我希望显示的信息卡将具有与返回的信息卡的文本相对应的文本,但是始终会出现默认情况。我已逐步完成代码,返回了正确的小部件,并且此后未返回默认小部件,因此应显示它,但不显示。
编辑: _buildInfoCard方法在streambuilder内部被调用。
答案 0 :(得分:2)
您需要为StatefulWidget
的每个实例提供一个密钥,否则它们可能会共享状态,如下所示:
Widget _buildInfoCard(LoginStatus status) {
switch (status) {
case LoginStatus.LOGIN_FAILED:
return InfoCard(
key: ValueKey(status),
message: "Login failed, please check your username and password.",
);
default:
return InfoCard(
key: ValueKey(status),
message: "Please login with your username and password",
);
}
}
关于为什么我们在这里需要键的很好的文章:ItemAppearanceObjects
答案 1 :(得分:1)
对于遇到相同问题的任何人,请点击Jordan Davies提供的链接,然后在YouTube上观看Flutter 101的第2集以了解更多信息。
问题在于,当您构建窗口小部件树时,flutter框架会将这些窗口小部件转换为元素,然后将其用于呈现UI。
当flutter框架构造元素树时,它将查看每个小部件,并将小部件类型与树中给定位置的元素类型进行比较。如果类型相同,则flutter可能会重复使用该元素。
有状态的小部件具有长寿命的状态对象,当将新的小部件添加到元素树时,它们可能不会被包装元素删除。在这种情况下,新返回的窗口小部件可以使用先前呈现的有状态窗口小部件中的现有状态对象。
解决方案如约旦建议的那样,使用键来防止这种情况发生,或者使用无状态小部件。有状态小部件上还有其他方法也可以使用,但乔丹的答案最能满足我的期望。