在 Flutter 中处理布尔实例的问题 class
Issue with handling boolean instance in Flutter class
在我的 flutter 应用程序中,我有一个 class 和一个 class 列表,如下所示:
class GuestType {
final String name;
bool isActive;
GuestType({this.name, this.isActive});
}
List<GuestType> _guestTypes = [
GuestType(name: 'White', isActive: false),
GuestType(name: 'Blue', isActive: false),
GuestType(name: 'Lavander', isActive: false),
GuestType(name: 'Green', isActive: false),
GuestType(name: 'Pink', isActive: false),
GuestType(name: 'Yellow', isActive: false)
];
我正在通过 _guestTypes 进行映射并创建包含名称实例的卡片。
每张卡片都有 onPress 属性,我需要实现的是当卡片被按下时,isActive 实例设置为 true。但是,任何时候只有一张牌可以为真,所以当按下一张牌时,所有其他牌都必须设置为假。
这是我实现预期结果的代码:
...
children: _guestTypes
.map(
(type) => Card(
colour: type.isActive == true
? widgetAttivo
: widgetInattivo,
onPress: () {
setState(() {
_guestTypes
.map((guest) => guest.isActive == true
? setState(() {
guest.isActive = false;
type.isActive = !type.isActive;
})
: setState(() {
type.isActive = !type.isActive;
}));
});
},
...
此代码无效,我仍然可以select并激活多张卡。
有线索吗?
非常感谢。
在您的 setState
调用中,您正在重新映射 _guestTypes
,但未对 return 值执行任何操作。 map()
没有就地映射,它 return 是更新的地图。
此外,您不需要在地图功能内外都使用setState
,只需将其设置在您要更新的内容周围就足够了(而且更好)。
() {
setState(() {
// notice the change here - use the result and set the value in the state
_guestTypes = _guestTypes
.map((guest) {
// set `true` for same guest type, `false` for others.
// (use a different condition to compare them if that isn't good enough)
guest.isActive = type.name == guest.name;
// needs to return the final value for each item
return guest;
}).toList();
});
},
使用 map
并在回调中更改某些属性不会影响您当前的列表(这就是映射 returns Iterable
的原因)。
因此,作为解决方案,我将提出以下建议:
setState(() {
_guestTypes = _guestTypes.map((guest) {
if(guest.name == type.name){
guest.isActive = true;
}else{
guest.isActive = false;
}
return guest;
}).toList();
});
您必须检查所选项目名称是否与地图中的项目名称相同。使其 isActive 为真,其他所有为假。
您使用的工具错误。 map
是一种通过将每个项目映射到新项目来创建新迭代的方法。那不是你想要的。您只想迭代现有项目。这一直是 loop:
的工作
onPress: () {
setState(() {
for(var guest in _guestTypes) {
guest.isActive = false;
type.isActive = !type.isActive;
}
}
}
我还缩短了你的循环体。它做同样的事情,但代码减少了一半。
在我的 flutter 应用程序中,我有一个 class 和一个 class 列表,如下所示:
class GuestType {
final String name;
bool isActive;
GuestType({this.name, this.isActive});
}
List<GuestType> _guestTypes = [
GuestType(name: 'White', isActive: false),
GuestType(name: 'Blue', isActive: false),
GuestType(name: 'Lavander', isActive: false),
GuestType(name: 'Green', isActive: false),
GuestType(name: 'Pink', isActive: false),
GuestType(name: 'Yellow', isActive: false)
];
我正在通过 _guestTypes 进行映射并创建包含名称实例的卡片。 每张卡片都有 onPress 属性,我需要实现的是当卡片被按下时,isActive 实例设置为 true。但是,任何时候只有一张牌可以为真,所以当按下一张牌时,所有其他牌都必须设置为假。
这是我实现预期结果的代码:
...
children: _guestTypes
.map(
(type) => Card(
colour: type.isActive == true
? widgetAttivo
: widgetInattivo,
onPress: () {
setState(() {
_guestTypes
.map((guest) => guest.isActive == true
? setState(() {
guest.isActive = false;
type.isActive = !type.isActive;
})
: setState(() {
type.isActive = !type.isActive;
}));
});
},
...
此代码无效,我仍然可以select并激活多张卡。
有线索吗?
非常感谢。
在您的 setState
调用中,您正在重新映射 _guestTypes
,但未对 return 值执行任何操作。 map()
没有就地映射,它 return 是更新的地图。
此外,您不需要在地图功能内外都使用setState
,只需将其设置在您要更新的内容周围就足够了(而且更好)。
() {
setState(() {
// notice the change here - use the result and set the value in the state
_guestTypes = _guestTypes
.map((guest) {
// set `true` for same guest type, `false` for others.
// (use a different condition to compare them if that isn't good enough)
guest.isActive = type.name == guest.name;
// needs to return the final value for each item
return guest;
}).toList();
});
},
使用 map
并在回调中更改某些属性不会影响您当前的列表(这就是映射 returns Iterable
的原因)。
因此,作为解决方案,我将提出以下建议:
setState(() {
_guestTypes = _guestTypes.map((guest) {
if(guest.name == type.name){
guest.isActive = true;
}else{
guest.isActive = false;
}
return guest;
}).toList();
});
您必须检查所选项目名称是否与地图中的项目名称相同。使其 isActive 为真,其他所有为假。
您使用的工具错误。 map
是一种通过将每个项目映射到新项目来创建新迭代的方法。那不是你想要的。您只想迭代现有项目。这一直是 loop:
onPress: () {
setState(() {
for(var guest in _guestTypes) {
guest.isActive = false;
type.isActive = !type.isActive;
}
}
}
我还缩短了你的循环体。它做同样的事情,但代码减少了一半。