如何在 Flutter 中处理动态生成的 ListView 的选定项

Posted

技术标签:

【中文标题】如何在 Flutter 中处理动态生成的 ListView 的选定项【英文标题】:How to handle selected item for dynamically generated ListView in Flutter 【发布时间】:2021-12-19 09:51:52 【问题描述】:

最终变体Map = HashMap();

在这张地图上,我有

key -> ["color"] = value -> ["White", "Black"]; 键 -> ["ram"] = 值 -> ["128GB", "256GB"];

根据这些信息,我设计了以下 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 时,同样的索引颜色也会被选中,反之亦然。

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

【问题讨论】:

您是否在此 UI 中使用某种对话框?在showModalBottomSheet 上吗? 您似乎对多个功能使用相同的isSelectedIndex ,您需要制作地图,其中键将为功能名称,值将为每个功能的isSelectedIndex @YeasinSheikh 是的 @AbrarMalekji 这里键也是 UI 的值。请参阅用户界面。我使用键作为值的标题。另见代码。 map key 是标签,list 是标签的值 @AbrarMalekji 我将如何将所选索引添加到地图中。 map 只接收键和值。这里的值是一个列表 【参考方案1】:

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

class Value

     String valueName;
     bool isSelected;


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

class Model 

  String label;
  List<Value> valueList;


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

【讨论】:

以上是关于如何在 Flutter 中处理动态生成的 ListView 的选定项的主要内容,如果未能解决你的问题,请参考以下文章

flutter中List遍历

flutter中List遍历

flutter中List遍历

如何在 Flutter 中运行时生成 Sceneform 资源

如何从 Flutter 中的网格视图计数访问生成列表中的特定单元格?

Flutter:如何调用本地 JSON 数据并动态添加到标签栏?