import 'dart:convert'; import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter/services.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map/src/consts/map_constants.dart'; import 'package:flutter_map/src/entity/camera_position.dart'; import 'package:flutter_map/src/entity/codable.dart'; import 'package:flutter_map/src/entity/lat_lng.dart'; import 'package:flutter_map/src/entity/marker.dart'; import 'package:flutter_map/src/interface/map_fun_interface.dart'; import 'package:flutter_map/src/interface/map_marker_interface.dart'; import 'package:flutter_map/src/interface/map_polyline_interface.dart'; import '../entity/map_padding.dart'; class MapController implements MapMarkerInterface, MapFunInterface, MapPolylineInterface { final _pendingOperations = >[]; MethodChannel? _channel; bool _isDisposed = false; void setChannel(MethodChannel channel) { if (_isDisposed) return; _channel = channel; for (final op in _pendingOperations) { _executeMethod(op); } _pendingOperations.clear(); } void _executeMethod(Map op) { _channel?.invokeMethod(op['method'], op['args']).catchError((e) { debugPrint('Method ${op['method']} failed: $e'); }); } void dispose() { _isDisposed = true; _pendingOperations.clear(); _channel?.setMethodCallHandler(null); _channel = null; } @override void updateOrAddMarkers(List markers) { if (_isDisposed || markers.isEmpty) return; final serialized = _encodeJson(markers); final params = { 'method': MapConstants.methodUpdateOrAddMarkers, 'args': serialized }; debugPrint("updateOrAddMarkers...params==>$params"); if (_channel != null) { _executeMethod(params); } else { _pendingOperations.add(params); } } @override void moveCamera(CameraPosition cameraPosition) { if (_isDisposed) return; final serialized = cameraPosition.toJson(); final params = { 'method': MapConstants.methodMapMoveCamera, 'args': serialized }; debugPrint("moveCamera...params==>$params"); if (_channel != null) { _executeMethod(params); } else { _pendingOperations.add(params); } } @override void animateCamera(CameraPosition cameraPosition) { if (_isDisposed) return; final serialized = cameraPosition.toJson(); final params = { 'method': MapConstants.methodMapAnimateCamera, 'args': serialized }; debugPrint("animateCamera...params==>$params"); if (_channel != null) { _executeMethod(params); } else { _pendingOperations.add(params); } } @override void updateOrAddMarker(Marker marker) { updateOrAddMarkers([marker]); } @override void replaceAllMarkers(List markers) { if (_isDisposed) return; final serialized = _encodeJson(markers); final params = { 'method': MapConstants.methodReplaceAllMarkers, 'args': serialized }; debugPrint("replaceAllMarkers...params==>$params"); if (_channel != null) { _executeMethod(params); } else { _pendingOperations.add(params); } } @override void clearAllMarkers() { replaceAllMarkers([]); } @override void addPolyline(List points, {bool isAnimateCamera = true, MapPadding? mapPadding}) { if (_isDisposed || points.isEmpty) return; Map map = {}; map['points'] = _encodeJson(points); map['isAnimateCamera'] = isAnimateCamera; if (mapPadding != null) { map['mapPadding'] = _encodeJson(mapPadding); } final params = {'method': MapConstants.methodAddPolyline, 'args': map}; debugPrint("addPolyline...params==>$params"); if (_channel != null) { _executeMethod(params); } else { _pendingOperations.add(params); } } @override void clear() { if (_isDisposed) return; clearAllMarkers(); final params = {'method': MapConstants.methodMapClear, 'args': ''}; debugPrint("clear...params==>$params"); if (_channel != null) { _executeMethod(params); } else { _pendingOperations.add(params); } } /// iOS 需要一个Map 而不是json string dynamic _encodeJson(dynamic object) { // iOS平台直接返回对象或转换为JSON对象 if (Platform.isIOS) { if (object is List) { return object.map((item) => item is Codable ? item.toJson() : item).toList(); } return object is Codable ? object.toJson() : object; } // 其他平台序列化为JSON字符串 return jsonEncode(object); } }