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

Flutter中生成TextButton列表时如何正确获取点击对应索引?

问题:循环生成的TextButton点击总是输出最后一个index值怎么解决?

我写了一段生成TableRow列表的代码,循环里给每个TextButton绑定了点击事件,想打印对应的index,但不管点哪个按钮,控制台都只输出循环最后一个index的值。

简化后的核心代码:

list.add(TextButton(
              onPressed: () {
                int temp = index;
                print(temp);
              },
              child: Text(myText),
));

完整函数代码:

List<TableRow> generateTables() {
    List<TableRow> list = [];

    int index = 0;

    for (Map element in exerciseList) {
      String exName = element["name"];
      Icon? icon = correspIcon(element);
      list.add(
        TableRow(
          children: [
            TextButton(
              onPressed: () {
                int temp = index;
                print(temp);
              },
              style: TextButton.styleFrom(
                minimumSize: Size.zero,
                padding: const EdgeInsets.all(4.0),
                tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                alignment: Alignment.centerLeft,
              ),
              child: Text(
                exName,
                style: TextStyle(
                    fontFamily: "ArialRounded",
                    fontSize: 20,
                    color: Colors.white.withAlpha(240)),
              ),
            ),
            icon ?? const SizedBox()
          ],
        ),
      );

      index++;
    }
    return list;
  }

我希望点击第n个TextButton时,能输出对应的n-1索引,该怎么改?


解决方案

这是Dart闭包捕获变量的常见问题:所有onPressed闭包都捕获了同一个index变量的引用,而非当前循环的数值。循环结束后index已经是最后一个值,所以所有按钮点击时都会读取这个最终值。

方法1:循环内创建局部变量捕获当前index

每次循环时,把当前index赋值给局部变量,让闭包捕获这个局部变量的数值:

for (Map element in exerciseList) {
  String exName = element["name"];
  Icon? icon = correspIcon(element);
  // 用局部变量保存当前循环的index值
  int currentIndex = index;
  list.add(
    TableRow(
      children: [
        TextButton(
          onPressed: () {
            print(currentIndex);
          },
          // 原有样式、child代码保持不变
        ),
        icon ?? const SizedBox()
      ],
    ),
  );
  index++;
}

方法2:使用asMap().forEach带索引遍历

借助列表的asMap()方法将列表转为键值对(键为索引,值为元素),再用forEach遍历,直接获取当前元素的索引:

List<TableRow> generateTables() {
    List<TableRow> list = [];

    exerciseList.asMap().forEach((index, element) {
      String exName = element["name"];
      Icon? icon = correspIcon(element);
      list.add(
        TableRow(
          children: [
            TextButton(
              onPressed: () {
                print(index);
              },
              style: TextButton.styleFrom(
                minimumSize: Size.zero,
                padding: const EdgeInsets.all(4.0),
                tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                alignment: Alignment.centerLeft,
              ),
              child: Text(
                exName,
                style: TextStyle(
                    fontFamily: "ArialRounded",
                    fontSize: 20,
                    color: Colors.white.withAlpha(240)),
              ),
            ),
            icon ?? const SizedBox()
          ],
        ),
      );
    });
    return list;
  }

方法3:使用List.generate生成列表

如果exerciseList是固定长度的列表,直接用List.generate创建TableRow列表,可直接获取当前索引:

List<TableRow> generateTables() {
  return List.generate(exerciseList.length, (index) {
    Map element = exerciseList[index];
    String exName = element["name"];
    Icon? icon = correspIcon(element);
    return TableRow(
      children: [
        TextButton(
          onPressed: () {
            print(index);
          },
          style: TextButton.styleFrom(
            minimumSize: Size.zero,
            padding: const EdgeInsets.all(4.0),
            tapTargetSize: MaterialTapTargetSize.shrinkWrap,
            alignment: Alignment.centerLeft,
          ),
          child: Text(
            exName,
            style: TextStyle(
                fontFamily: "ArialRounded",
                fontSize: 20,
                color: Colors.white.withAlpha(240)),
          ),
        ),
        icon ?? const SizedBox()
      ],
    );
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:15:30