Flutter中flutter_map标记点编号显示错误问题求助
解决Flutter中Marker编号全部显示最后一个值的问题
这是一个典型的Dart闭包变量捕获问题,我之前也踩过类似的坑,给你拆解下原因和解决办法:
问题根源
你在循环里创建Marker的builder时,Text组件引用的是外部的num变量。但Dart的闭包捕获的是变量的引用,不是当前循环迭代时的数值。当整个循环跑完,num最终变成了8(你从1开始循环6次,结束后num自然走到8),所有Marker的builder闭包在后续渲染时,都会读取这个已经更新后的num值,所以所有标记点都显示8。
解决方案
核心思路就是让每个闭包捕获的是当前迭代的固定值,而不是一个会被后续循环修改的变量引用。这里有两种简单的实现方式:
方法1:循环内创建局部变量保存当前序号
在每次循环里,把当前的num赋值给一个局部变量,让闭包捕获这个不会被后续修改的局部值:
if (state is TrackedRoute) { route.clear(); trackedPoints.clear(); int num = 1; setState(() { route = state.trackedRoute; }); for (int i = 0; i < route.length; i++) { LatLng element = route[i]; print('@@@@@ num is $num'); // 关键:创建局部变量保存当前num的数值 int currentNum = num; LatLng point = LatLng(element.latitude, element.longitude); Marker trackedPoint = Marker( point: point, height: 30, width: 30, builder: (context) => Stack( alignment: Alignment.topCenter, children: [ IconButton( icon: Icon(Icons.add_location), color: Colors.greenAccent, iconSize: 30, onPressed: () {}, ), Text( currentNum.toString(), // 使用局部变量而非外部num style: TextStyle(color: Colors.red, fontSize: 25), ), ], ), ); trackedPoints.add(trackedPoint); num++; } }
方法2:改用带索引的forEach循环(更简洁)
直接利用asMap()把列表转成索引-元素的映射,通过索引直接生成序号,彻底避免外部变量的问题:
if (state is TrackedRoute) { route.clear(); trackedPoints.clear(); setState(() { route = state.trackedRoute; }); // 用asMap()获取索引,直接生成从1开始的序号 route.asMap().forEach((index, element) { int currentNum = index + 1; LatLng point = LatLng(element.latitude, element.longitude); Marker trackedPoint = Marker( point: point, height: 30, width: 30, builder: (context) => Stack( alignment: Alignment.topCenter, children: [ IconButton( icon: Icon(Icons.add_location), color: Colors.greenAccent, iconSize: 30, onPressed: () {}, ), Text( currentNum.toString(), style: TextStyle(color: Colors.red, fontSize: 25), ), ], ), ); trackedPoints.add(trackedPoint); }); }
验证效果
修改后,每个Marker的Text都会捕获到当前迭代的固定序号,不会再跟着外部变量的最终值走,你就能看到标记点显示正确的2到7(或者从1开始的对应序号)了。
内容的提问来源于stack exchange,提问作者Vincenzo
相关产品推荐
相关产品推荐

