如何在 Flutter 中处理动态生成的 ListView 的选定项
How to handle selected item for dynamically generated ListView in Flutter
最终变体Map = HashMap();
在这张地图中,我有
key -> ["color"] = value -> ["White", "Black"];
键 -> ["ram"] = 值 -> ["128GB", "256GB"];
根据这些信息我设计了下面的UI.
**我想要 -> 如果我 select 白色,白色将 selected 而黑色将保持未 selected。如果我 select 黑色白色将变成未 selected。
拉姆也是如此。选择一个将使另一个未selected。两个列表视图 selection 将独立工作。 **
对于单个列表视图,我们可以使用 selectedIndex 变量来实现。
这是 API 的回复。这里的属性值可以是多个。但是我需要在 UI 中显示一个值。所以经过一些逻辑,我将标签和值存储到地图中。
"productVariation": [
{
"price": 406089.25,
"qty": 449,
"variationAttribute": [
{
"attribute_value": "White",
"attributeDetails": {
"attributeLabel": [
{
"label": "Color"
}
]
}
},
{
"attribute_value": "128GB",
"attributeDetails": {
"attributeLabel": [
{
"label": "Ram"
}
]
}
}
]
},
{
"price": 292561.69,
"qty": 246,
"variationAttribute": [
{
"attribute_value": "White",
"attributeDetails": {
"attributeLabel": [
{
"label": "Color"
}
]
}
},
{
"attribute_value": "256GB",
"attributeDetails": {
"attributeLabel": [
{
"label": "Ram"
}
]
}
}
]
},
{
"price": 951456.88,
"qty": 828,
"variationAttribute": [
{
"attribute_value": "Black",
"attributeDetails": {
"attributeLabel": [
{
"label": "Color"
}
]
}
},
{
"attribute_value": "128GB",
"attributeDetails": {
"attributeLabel": [
{
"label": "Ram"
}
]
}
}
]
},
{
"price": 930735.09,
"qty": 321,
"variationAttribute": [
{
"attribute_value": "Black",
"attributeDetails": {
"attributeLabel": [
{
"label": "Color"
}
]
}
},
{
"attribute_value": "256GB",
"attributeDetails": {
"attributeLabel": [
{
"label": "Ram"
}
]
}
}
]
}
]
这是 UI 代码。此代码用于底部 sheet 对话框。
variationView() {
final widgets = <Widget>[];
var i = 1; // maintain vertical dot line between variation
for (var key in widget.controller.variationMap.keys) {
final list = widget.controller.variationMap[key];
widgets.add(
GlobalText(
str: "Select $key",
fontSize: 18,
fontWeight: FontWeight.w300,
),
);
widgets.add(
const SizedBox(
height: 20,
),
);
widgets.add(
SizedBox(
height: 60,
child: ListView.builder(
itemCount: list!.length,
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (ctx, index) {
return GestureDetector(
onTap: () {
setState(() {
isSelectedIndex = index;
isSelectedIndexForListView = i;
});
},
child:Container(
margin: EdgeInsets.only(right: 11),
padding: EdgeInsets.all(4),
width: 60,
height: 55,
decoration: BoxDecoration(
color: Color(0xfff8f8f8),
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: isSelectedIndex == index && isSelectedIndexForListView == i
? Colors.black
: Color(0xffe2e2e2),
width: 1,
),
),
child: Center(
child: GlobalText(
str: list[index],
color: Color(0xff535960),
fontSize: 13,
fontWeight: FontWeight.w400,
maxLines: 2,
),
),
),
);
},
),
),
);
if (i < widget.controller.variationMap.keys.length) {
widgets.add(
const SizedBox(
height: 30,
),
);
}
i++;
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: widgets,
);
}
我尝试了多种方法,但未能保持或管理 selected 项目的状态。
在这段代码中,我试图保存列表视图的索引和另一个用于项目 selected 的索引。但是当我 select 一个 ram 时,所以相同的索引颜色也会 selected,反之亦然。
我也尝试过使用唯一键。但未能解决问题。
首先,您可以为值创建一个模型 class,其中一个用于值名称,另一个用于检查它是否被选中。
class Value{
String valueName;
bool isSelected;
}
然后创建另一个 class,它将有一个字符串类型的字段,即标签和另一个值对象列表类型的字段。
class Model {
String label;
List<Value> valueList;
}
从您的控制器或视图模型 class 或您用来更新状态的 class,您只需更新 isSelected
字段的值。
最终变体Map = HashMap
在这张地图中,我有
key -> ["color"] = value -> ["White", "Black"]; 键 -> ["ram"] = 值 -> ["128GB", "256GB"];
根据这些信息我设计了下面的UI.
**我想要 -> 如果我 select 白色,白色将 selected 而黑色将保持未 selected。如果我 select 黑色白色将变成未 selected。 拉姆也是如此。选择一个将使另一个未selected。两个列表视图 selection 将独立工作。 **
对于单个列表视图,我们可以使用 selectedIndex 变量来实现。
这是 API 的回复。这里的属性值可以是多个。但是我需要在 UI 中显示一个值。所以经过一些逻辑,我将标签和值存储到地图中。
"productVariation": [
{
"price": 406089.25,
"qty": 449,
"variationAttribute": [
{
"attribute_value": "White",
"attributeDetails": {
"attributeLabel": [
{
"label": "Color"
}
]
}
},
{
"attribute_value": "128GB",
"attributeDetails": {
"attributeLabel": [
{
"label": "Ram"
}
]
}
}
]
},
{
"price": 292561.69,
"qty": 246,
"variationAttribute": [
{
"attribute_value": "White",
"attributeDetails": {
"attributeLabel": [
{
"label": "Color"
}
]
}
},
{
"attribute_value": "256GB",
"attributeDetails": {
"attributeLabel": [
{
"label": "Ram"
}
]
}
}
]
},
{
"price": 951456.88,
"qty": 828,
"variationAttribute": [
{
"attribute_value": "Black",
"attributeDetails": {
"attributeLabel": [
{
"label": "Color"
}
]
}
},
{
"attribute_value": "128GB",
"attributeDetails": {
"attributeLabel": [
{
"label": "Ram"
}
]
}
}
]
},
{
"price": 930735.09,
"qty": 321,
"variationAttribute": [
{
"attribute_value": "Black",
"attributeDetails": {
"attributeLabel": [
{
"label": "Color"
}
]
}
},
{
"attribute_value": "256GB",
"attributeDetails": {
"attributeLabel": [
{
"label": "Ram"
}
]
}
}
]
}
]
这是 UI 代码。此代码用于底部 sheet 对话框。
variationView() {
final widgets = <Widget>[];
var i = 1; // maintain vertical dot line between variation
for (var key in widget.controller.variationMap.keys) {
final list = widget.controller.variationMap[key];
widgets.add(
GlobalText(
str: "Select $key",
fontSize: 18,
fontWeight: FontWeight.w300,
),
);
widgets.add(
const SizedBox(
height: 20,
),
);
widgets.add(
SizedBox(
height: 60,
child: ListView.builder(
itemCount: list!.length,
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (ctx, index) {
return GestureDetector(
onTap: () {
setState(() {
isSelectedIndex = index;
isSelectedIndexForListView = i;
});
},
child:Container(
margin: EdgeInsets.only(right: 11),
padding: EdgeInsets.all(4),
width: 60,
height: 55,
decoration: BoxDecoration(
color: Color(0xfff8f8f8),
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: isSelectedIndex == index && isSelectedIndexForListView == i
? Colors.black
: Color(0xffe2e2e2),
width: 1,
),
),
child: Center(
child: GlobalText(
str: list[index],
color: Color(0xff535960),
fontSize: 13,
fontWeight: FontWeight.w400,
maxLines: 2,
),
),
),
);
},
),
),
);
if (i < widget.controller.variationMap.keys.length) {
widgets.add(
const SizedBox(
height: 30,
),
);
}
i++;
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: widgets,
);
}
我尝试了多种方法,但未能保持或管理 selected 项目的状态。
在这段代码中,我试图保存列表视图的索引和另一个用于项目 selected 的索引。但是当我 select 一个 ram 时,所以相同的索引颜色也会 selected,反之亦然。
我也尝试过使用唯一键。但未能解决问题。
首先,您可以为值创建一个模型 class,其中一个用于值名称,另一个用于检查它是否被选中。
class Value{
String valueName;
bool isSelected;
}
然后创建另一个 class,它将有一个字符串类型的字段,即标签和另一个值对象列表类型的字段。
class Model {
String label;
List<Value> valueList;
}
从您的控制器或视图模型 class 或您用来更新状态的 class,您只需更新 isSelected
字段的值。