You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何声明、初始化并使用List<List<String>>?

问题

需求为点击Category组件时,获取并展示对应分类下的items名称。需要为每个分类维护一个String类型列表,尝试使用List<List<String>>但在声明、初始化及赋值过程中多次失败,出现RangeError错误。

尝试的代码片段

代码片段1

List<List<String>> itemsList = [[]];
Container(
    child: ListView.builder(
    itemCount: itemsCategories.length ,
    itemBuilder: (context, index) {
      return Card(
        child: Column(
          children: [
            InkWell(
              onTap:() async{
                List<String> tempList = await getItems();
                // add to list of list
                for (var element in temp) {  itemsList [index].add(element);  }

                print( 'tempList[index] items: ${tempList[index]}');
              },
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Text(itemsCategories[index].name),
              ),
            ),
          ],
        ),
      );
    }
 ),
)

代码片段2

// assign value one by one
for (var i = 0; i < tempList.length; i++) {
  itemsList[index][i]= tempList [i];
  print( itemsList[index][i]);
}

错误信息

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: RangeError (index): Invalid value: Valid value range is empty: 0
E/flutter ( 8581): #0      List.[] (dart:core-patch/growable_array.dart:264:36)
E/flutter ( 8581): #1      _HomeState.build..

解决方案

1. 正确使用List<List<String>>的方法

初始化

核心问题是初始化时itemsList仅包含一个空列表,但分类数量为itemsCategories.length,当index >=1时,itemsList[index]不存在,触发RangeError。正确初始化需为每个分类提前创建空列表:

// 在State类中声明
List<List<String>> itemsList = [];

@override
void initState() {
  super.initState();
  // 为每个分类生成一个空列表
  itemsList = List.generate(itemsCategories.length, (_) => []);
}

赋值操作

点击分类获取数据后,通过setState更新对应索引的列表,确保UI同步刷新:

onTap:() async{
  List<String> tempList = await getItems();
  // 方式1:直接替换该分类的列表(适用于每次点击重新获取最新数据)
  setState(() {
    itemsList[index] = tempList;
  });
  // 方式2:往已有列表追加元素(适用于增量加载场景)
  // setState(() {
  //   itemsList[index].addAll(tempList);
  // });
  print('分类${index}的items: ${itemsList[index]}');
}

2. 更直观的替代方案:使用Map存储分类与items的对应关系

如果分类有唯一标识(如id或name),使用Map<String, List<String>>可避免索引匹配错误,逻辑更直观:

// 在State类中初始化
Map<String, List<String>> categoryItems = {};

// 点击赋值逻辑
onTap:() async{
  List<String> tempList = await getItems();
  setState(() {
    // 以分类名称作为key存储对应items列表
    categoryItems[itemsCategories[index].name] = tempList;
  });
  // 通过分类名称直接获取对应items
  print('${itemsCategories[index].name}的items: ${categoryItems[itemsCategories[index].name]}');
}

3. 展示items的实现

在Card的Column中添加items展示区域,使用嵌套的ListView.builder实现:

Card(
  child: Column(
    children: [
      InkWell(/* 点击逻辑部分 */),
      // 仅当当前分类有items时展示
      if (itemsList[index].isNotEmpty)
        ListView.builder(
          shrinkWrap: true,
          physics: const NeverScrollableScrollPhysics(),
          itemCount: itemsList[index].length,
          itemBuilder: (context, itemIndex) {
            return Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
              child: Text(itemsList[index][itemIndex]),
            );
          },
        ),
    ],
  ),
)

内容的提问来源于stack exchange,提问作者Hesham Elkotabi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 22:01:01