多边形(Polygon)用于在地图上绘制封闭区域,支持填充色、描边、虚线、纹理描边和带洞多边形。
本文档介绍 Polygon 的创建、样式配置以及带洞多边形的注意事项。
Polygon(
id: 'pg1',
points: const [
LatLng(39.90, 116.39),
LatLng(39.90, 116.42),
LatLng(39.93, 116.42),
LatLng(39.93, 116.39),
],
fillColor: const Color(0x7F00FF00),
strokeColor: const Color(0xFF000000),
strokeWidth: 5,
)
添加到地图:
TencentMap(
polygons: {polygon},
...
)
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
id |
String? |
自动生成 | 唯一标识 |
points |
List<LatLng> |
必填 | 外轮廓顶点(≥3 个) |
holePoints |
List<List<LatLng>> |
[] |
洞的坐标列表 |
fillColor |
Color |
Color(0x7F00FF00) |
填充色 |
strokeColor |
Color |
Color(0xFF000000) |
描边色 |
strokeWidth |
double |
10 |
描边宽度(逻辑像素) |
dashPattern |
List<int> |
[] |
虚线模式 |
strokeTexture |
BitmapDescriptor? |
null | 纹理描边 |
strokeTextureSpacing |
int |
0 |
纹理间距 |
displayLevel |
int |
2 |
显示层级 |
visible |
bool |
true |
是否可见 |
zIndex |
int |
0 |
层级 |
onTap |
PolygonTapCallback? |
null | 点击回调(参数为 polygonId) |
Polygon(
id: 'pg1',
points: points,
fillColor: const Color(0x7F0000FF), // 半透明蓝色填充
strokeColor: const Color(0xFF000000), // 黑色描边
strokeWidth: 5,
)
Polygon(
id: 'dashed',
points: points,
fillColor: Colors.transparent,
strokeColor: Colors.red,
dashPattern: [20, 10], // 20px 实线 + 10px 空白
)
Polygon(
id: 'texture',
points: points,
strokeTexture: BitmapDescriptor.fromAsset('assets/border_texture.png'),
strokeTextureSpacing: 0,
strokeWidth: 20,
)
注意:
strokeTexture和dashPattern互斥,设置纹理后虚线不生效。
带洞多边形允许在一个外轮廓内挖出一个或多个洞:
Polygon(
id: 'withHole',
points: outerPoints, // 外轮廓
holePoints: [
// 第一个洞
[
LatLng(39.91, 116.40),
LatLng(39.91, 116.41),
LatLng(39.92, 116.41),
LatLng(39.92, 116.40),
],
],
fillColor: const Color(0x7F00FF00),
strokeColor: Colors.black,
)
Polygon 通过 Set<Polygon> 以声明式方式管理。插件在 Widget 重建时自动 diff 新旧两个 Set,计算出增/删/改三类变更并推送到原生层:
id 索引:内部用 Map<String, Polygon> 索引,不依赖 Set 的 hashCode==:Polygon 重写了 ==,比较 points/holePoints/fillColor/strokeWidth/dashPattern 等全部业务属性(⚠️ 也比较 onTap 回调)@immutable,修改属性必须用 copyWith 创建新对象final Map<String, Polygon> _polygons = {};
// 添加
_polygons['pg1'] = Polygon(
id: 'pg1',
points: const [
LatLng(39.90, 116.39),
LatLng(39.90, 116.42),
LatLng(39.93, 116.42),
LatLng(39.93, 116.39),
],
fillColor: const Color(0x7F00FF00),
);
// 更新(必须 copyWith,不能原地改字段)
_polygons['pg1'] = _polygons['pg1']!.copyWith(fillColor: Colors.red);
// 更新点位(points 是 List,必须创建新 List)
_polygons['pg1'] = _polygons['pg1']!.copyWith(
points: [..._polygons['pg1']!.points, const LatLng(39.94, 116.40)],
);
// 删除
_polygons.remove('pg1');
// 传入 Widget
TencentMap(polygons: Set<Polygon>.of(_polygons.values));
| 错误写法 | 原因 | 正确写法 |
|---|---|---|
原地修改 points / holePoints 列表:polygon.points.add(newPoint) |
Polygon 对象引用不变 → == 短路 identical → 判定无变化 → 不触发。即使列表内容变了,== 里的 _listEquals / _holeListEquals 也不会被执行 |
polygon.copyWith(points: [...polygon.points, newPoint]) |
在同一 Set 上 add copyWith 后的对象:_polygons.add(pg.copyWith(fillColor: Colors.red)) |
hashCode 仅基于 id(相同),但 == 为 false(属性不同)→ Set 同时保留新旧两个对象 → diff 按 id 索引只取最后一个,行为不可预测 |
创建全新 Set,或用 Map 管理 |
两个 Polygon 用同一个 id |
diff 按 id 索引成 Map 时后者覆盖前者 → 变更丢失 | 确保每个 Polygon 有唯一 id(不传 id 时自动生成) |
修改了 State 变量但没调 setState |
Widget 不重建 → didUpdateWidget 不触发 → diff 不执行 |
必须在 setState 内修改变量 |
提示:Polygon 的
==会比较onTap回调。如果在build方法中内联写onTap: () {},每次重建都会产生新的闭包引用 →onTap != oldOnTap→ 触发不必要的更新。建议将回调存储为成员变量。
有帮助
没帮助