如何在 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 字段的值。