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

Flutter中for循环内Text组件全部显示相同值的问题排查

问题根源:闭包捕获变量引用而非值

这是Dart开发中很常见的闭包陷阱——你在循环里创建的Marker的builder是一个闭包,它捕获的是_markersDistanceCount这个变量的引用,而不是循环迭代时该变量的具体值。

当整个for循环执行完毕后,_markersDistanceCount的值已经累加到25了。等到Flutter需要渲染这些Marker的UI时,所有闭包才会去读取这个变量的当前值,自然就全部显示25了。

为什么用i.toString()就正常?因为从Dart 2.2版本开始,for循环的迭代变量i在每次循环迭代时都会创建一个新的实例,闭包捕获的是每次迭代的i本身,所以每个Text组件拿到的都是对应循环步骤的正确值。

解决方案

方案一:创建局部变量保存当前值

在循环内部定义一个局部变量,把当前的_markersDistanceCount值存进去,让闭包捕获这个局部变量(它的作用域仅限于当前循环迭代):

var _markersDistanceCount = 0;
for (var i = 0; i < 25; i++) {
  _markersDistanceCount++;
  final currentCount = _markersDistanceCount; // 关键:局部变量保存当前值
  print(_markersDistanceCount);
  markersDistance.add(
    Marker(
      point: LatLng(point.latitude, point.longitude),
      builder: (context) => CircleAvatar(
        radius: 50,
        backgroundColor: Colors.red,
        child: Text(currentCount.toString())
      ),
    ),
  );
}

方案二:直接复用循环变量i(适合你的场景)

既然你已经发现用i.toString()可以解决问题,这其实是最简洁的方式——因为Dart的循环迭代变量特性,每个闭包捕获的都是对应迭代的i实例,值自然正确:

for (var i = 0; i < 25; i++) {
  print(i + 1); // 和你的_markersDistanceCount逻辑一致
  markersDistance.add(
    Marker(
      point: LatLng(point.latitude, point.longitude),
      builder: (context) => CircleAvatar(
        radius: 50,
        backgroundColor: Colors.red,
        child: Text((i + 1).toString()) // 直接用i+1替代自增变量
      ),
    ),
  );
}

方案三:用函数封装捕获值

如果业务逻辑更复杂,可以把Text的创建封装成一个函数,通过参数传递当前值,利用函数参数的作用域来确保捕获的是正确值:

Widget buildCountText(int count) {
  // 函数参数会创建独立的作用域,闭包捕获的是当前传入的count值
  return Text(count.toString());
}

// 循环内调用:
var _markersDistanceCount = 0;
for (var i = 0; i < 25; i++) {
  _markersDistanceCount++;
  print(_markersDistanceCount);
  markersDistance.add(
    Marker(
      point: LatLng(point.latitude, point.longitude),
      builder: (context) => CircleAvatar(
        radius: 50,
        backgroundColor: Colors.red,
        child: buildCountText(_markersDistanceCount)
      ),
    ),
  );
}
为什么jsonEncode/jsonDecode没用?

你尝试的序列化反序列化操作,本质上只是把变量的值复制了一份,但如果没有把这个复制后的值存到一个局部变量里,而是直接在Text中使用jsonDecode(jsonEncode(_markersDistanceCount)),那么闭包执行时还是会去读取_markersDistanceCount的当前值(也就是循环结束后的25),自然无法解决问题。如果把序列化后的值存到局部变量再使用,其实就和方案一的逻辑一致了。

内容的提问来源于stack exchange,提问作者Bas van Dijk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 13:14:05