如何获取CarPlay CPPointOfInterestTemplate地图屏幕的经纬度范围?
在CarPlay的CPPointOfInterestTemplate中获取地图可视区域的经纬度范围
要实现地图滚动/位置变化时获取屏幕的经纬度范围,你需要利用CPMapTemplateDelegate的代理方法监听地图区域变化,具体步骤如下:
一、修改原生Swift代码(FCPPointOfInterestTemplate.swift)
- 让
FCPPointOfInterestTemplate类遵守CPMapTemplateDelegate协议,并将模板的代理设置为自身 - 实现区域变化的代理方法,提取可视区域的经纬度范围,再通过MethodChannel传递给Flutter端
修改后的代码如下:
// // FCPPointOfInterestTemplate.swift // flutter_carplay // // Created by Olaf Schneider on 15.02.22. // import CarPlay import Flutter @available(iOS 14.0, *) class FCPPointOfInterestTemplate: NSObject, CPMapTemplateDelegate { private(set) var _super: CPPointOfInterestTemplate? private(set) var elementId: String private var title: String private var poi: [FCPPointOfInterest] init(obj: [String: Any]) { self.elementId = obj["_elementId"] as! String self.title = obj["title"] as! String self.poi = (obj["poi"] as! [[String: Any]]).map { FCPPointOfInterest(obj: $0) } super.init() } var get: CPPointOfInterestTemplate { var pois: [CPPointOfInterest] = [] for p in poi { pois.append(p.get) } let pointOfInterestTemplate = CPPointOfInterestTemplate.init( title: self.title, pointsOfInterest: pois, selectedIndex: NSNotFound) // 设置代理,监听地图区域变化 pointOfInterestTemplate.delegate = self self._super = pointOfInterestTemplate return pointOfInterestTemplate } // 监听地图可视区域变化的代理方法 func mapTemplate(_ mapTemplate: CPMapTemplate, didChangeVisibleRegion visibleRegion: CPMapRegion) { // 提取可视区域的东北、西南角坐标 let northEast = visibleRegion.northEast let southWest = visibleRegion.southWest // 封装成可传递给Flutter的数据 let regionData = [ "northEastLat": northEast.latitude, "northEastLng": northEast.longitude, "southWestLat": southWest.latitude, "southWestLng": southWest.longitude, "elementId": self.elementId ] // 通过MethodChannel将数据发送到Flutter端 let channel = FlutterMethodChannel(name: "flutter_carplay/map_region", binaryMessenger: FlutterGetAppController.shared?.binaryMessenger ?? FlutterBinaryMessengerImpl()) channel.invokeMethod("onRegionChanged", arguments: regionData) } } @available(iOS 14.0, *) extension FCPPointOfInterestTemplate: FCPRootTemplate {}
二、Flutter端接收区域变化回调
在Flutter代码中,通过MethodChannel监听原生发送的区域变化事件,进而请求对应范围内的充电桩:
import 'package:flutter/services.dart'; class CarPlayMapHandler { final MethodChannel _channel = const MethodChannel('flutter_carplay/map_region'); void initRegionListener() { _channel.setMethodCallHandler((MethodCall call) async { if (call.method == 'onRegionChanged') { final Map<String, dynamic> args = call.arguments as Map<String, dynamic>; // 获取可视区域的经纬度范围 final double neLat = args['northEastLat']; final double neLng = args['northEastLng']; final double swLat = args['southWestLat']; final double swLng = args['southWestLng']; final String elementId = args['elementId']; // 根据范围请求充电桩数据 await _fetchChargingStations(neLat, neLng, swLat, swLng); } }); } Future<void> _fetchChargingStations(double neLat, double neLng, double swLat, double swLng) async { // 这里实现你的充电桩接口请求逻辑 // 例如:根据东北、西南角坐标构造范围查询条件 } }
关键说明
CPMapTemplateDelegate的mapTemplate:didChangeVisibleRegion:方法会在地图滚动、缩放、位置更新时触发,完全满足需求- 传递的
elementId可用于区分不同的模板实例(如有多个) - 确保MethodChannel的名称在原生和Flutter端完全一致,否则会导致通信失败
内容的提问来源于stack exchange,提问作者Ragul PR
相关产品推荐
相关产品推荐

