如何在syncfusion_flutter_maps中实现可点击Tooltip以执行自定义操作?
问题:Flutter Syncfusion Maps Tooltip点击即关闭,需实现点击触发导航等回调功能
在Flutter 3.13版本中使用syncfusion_flutter_maps包时,点击地图Marker的Tooltip会直接关闭,无法触发内部的导航按钮或其他自定义VoidCallback逻辑,现需解决该问题,让Tooltip点击时能正常执行预设的函数。
现有代码:
SfMaps( layers: [ MapTileLayer( urlTemplate: 'https://api.mapbox.com/styles/v1', zoomPanBehavior: cntrlr.mapZoomPanBehavior, tooltipSettings: MapTooltipSettings(color: Colors.white, hideDelay: 5.0), markerTooltipBuilder: (context, index) { Map<String, dynamic>? feature = cntrlr.markerDetails[index]; return GestureDetector( onTap: () { print("Pressssed"); }, child: Container( clipBehavior: Clip.antiAliasWithSaveLayer, width: kWidth(context) / 2, height: 200, padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration(color: Colors.white), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( feature['text'].toString(), style: TextStyle(fontSize: 16), maxLines: 2, overflow: TextOverflow.ellipsis, ), SizedBox(height: 12), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Image.asset( "assets/icons/location_red.png", height: 22, width: 22, ), SizedBox(width: 7), Expanded( child: Text( feature['place_name'].toString(), style: TextStyle(fontSize: 12), maxLines: 3, overflow: TextOverflow.ellipsis, ) ) ], ), SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ InkWell( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (_) => PreviewNavigationScreen( latitude: double.parse(feature['geometry']['coordinates'][1]), longitude: double.parse(feature['geometry']['coordinates'][0]), placeName: feature['place_name'].toString(), ) ) ); }, child: Image.asset( "assets/icons/route.png", height: 30, width: 30, ), ), Image.asset("assets/icons/phone.png", height: 30, width: 30), Image.asset("assets/icons/earth.png", height: 30, width: 30), Image.asset("assets/icons/email.png", height: 30, width: 30), ], ) ], ), ), ); }, initialFocalLatLng: MapLatLng(box.read('latitude'), box.read('longitude')), controller: cntrlr.controller2, initialMarkersCount: cntrlr.markers.length, markerBuilder: (BuildContext context, int index) => cntrlr.markers[index], ), ], ),
当前效果:

解决方案
问题根源在于Syncfusion Maps的Tooltip默认会在点击时触发隐藏逻辑,拦截了内部手势事件。可通过以下两种方式解决:
方法一:禁用Tooltip默认点击关闭行为
修改MapTooltipSettings,添加shouldHideOnTap: false配置,阻止Tooltip自动关闭,让内部手势组件正常响应事件:
tooltipSettings: MapTooltipSettings( color: Colors.white, hideDelay: 5.0, shouldHideOnTap: false, // 关键配置 ),
方法二:手动控制Tooltip显示/隐藏
若需要更灵活的状态管理,可通过MapTileLayerController手动控制Tooltip:
- 在页面中定义变量记录当前显示的Tooltip索引:
int? _activeTooltipIndex;
- 修改
markerTooltipBuilder中的手势逻辑,手动处理事件与Tooltip状态:
markerTooltipBuilder: (context, index) { Map<String, dynamic>? feature = cntrlr.markerDetails[index]; return GestureDetector( onTap: () { // 执行自定义导航或其他逻辑 Navigator.push( context, MaterialPageRoute(builder: (_) => PreviewNavigationScreen( latitude: double.parse(feature['geometry']['coordinates'][1]), longitude: double.parse(feature['geometry']['coordinates'][0]), placeName: feature['place_name'].toString(), )) ); // 按需手动关闭Tooltip cntrlr.controller2.hideTooltip(); }, child: // 原Tooltip内容 ); },
同时确保tooltipSettings中shouldHideOnTap设为false,避免默认行为干扰。
注意事项
- 使用方法一时,Tooltip会在
hideDelay时长后自动关闭,也可通过controller.hideTooltip()主动关闭。 - 若内部手势仍不响应,可开启
debugPaintPointersEnabled = true检查手势响应区域是否被遮挡。
内容的提问来源于stack exchange,提问作者malik_hammad
相关产品推荐
相关产品推荐

