首页 > 解决方案 > 如何在 Flutter 中处理动态生成的 ListView 的选定项

问题描述

最终的variationMap = HashMap<String, List>();

在这张地图中,我有

键 -> [“颜色”] = 值 -> [“白色”,“黑色”];键 -> [“内存”] = 值 -> [“128GB”,“256GB”];

基于此信息,我设计了以下 UI。

底页 UI

**我想要 -> 如果我选择白色,白色将被选中,黑色将保持未选中状态。如果我选择黑色白色将变为未选中。拉姆也是如此。选择一个将使另一个未选中。两个列表视图选择将独立工作。**

对于单个列表视图,我们可以使用 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"
                  }
                ]
              }
            }
          ]
        }
      ]

这是用户界面代码。此代码用于底部工作表对话框。

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,
    );
  }

我尝试了多种方法,但未能保持或管理所选项目的状态。

在这段代码中,我试图保存列表视图的索引和另一个用于项目选择的索引。但是当我选择一个 ram 时,同样的索引颜色也会被选中,反之亦然。

我也尝试过使用唯一键。但未能解决问题。

标签: flutterlistviewflutter-listview

解决方案


首先,您可以为 Value 创建一个模型类,它必须为值名称字段一个字段,另一个字段用于检查它是否被选中。

class Value{

     String valueName;
     bool isSelected;

}

然后创建另一个类,该类将具有一个 String 类型的字段,即标签和另一个 List of Value 对象类型的字段。

class Model {

  String label;
  List<Value> valueList;

}

从您的控制器或视图模型类或您用于更新状态的类中,您只需更新isSelected字段的值。


推荐阅读