import 'dart:convert'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter_map/src/consts/map_constants.dart'; import 'package:flutter_map/src/consts/marker_type.dart'; import 'package:flutter_map/src/core/map_controller.dart'; import 'package:flutter_map/src/entity/marker.dart'; import '../../flutter_map.dart'; import '../entity/polyline.dart'; class MapWidget extends StatefulWidget { final MapBaseController? controller; final MarkerTapCallback? onMarkerTap; final List? markers; final List? polyline; final MapPadding? mapPadding; final bool isAnimateCamera; final bool? isShowLogo; final bool? interactionIsEnabled; const MapWidget({ super.key, this.controller, this.onMarkerTap, this.mapPadding, this.markers, this.isAnimateCamera = true, this.isShowLogo, this.interactionIsEnabled, this.polyline, }); @override State createState() => _MapWidgetState(); } class _MapWidgetState extends State { final String mapViewType = MapConstants.mapWidgetViewType; final List cameraPoints = []; @override void didUpdateWidget(covariant MapWidget oldWidget) { super.didUpdateWidget(oldWidget); cameraPoints.clear(); if (oldWidget.markers != widget.markers) { if (widget.markers == null || widget.markers!.isEmpty) { widget.controller?.clearAllMarkers(); } else { showMarker(); } } if (oldWidget.polyline != widget.polyline) { widget.controller?.clearAllPolylines(); showPolyline(); } animateCamera(); } void showMarker() { if (widget.markers == null || widget.markers!.isEmpty) { return; } final markerPoints = widget.markers ?.map((marker) => LatLng(latitude: marker.latitude, longitude: marker.longitude)) .toList(); cameraPoints.addAll(markerPoints ?? []); widget.controller?.replaceAllMarkers(widget.markers ?? []); } void showPolyline() { if (widget.polyline == null || widget.polyline!.isEmpty) { return; } for (var line in widget.polyline!) { if (line.points.isNotEmpty) { cameraPoints.add(line.points.first); widget.controller?.addPolyline(line, isAnimateCamera: false); } } } void animateCamera() { if (cameraPoints.isNotEmpty) { widget.controller ?.moveToSuitableLocation(cameraPoints, mapPadding: widget.mapPadding); } } @override void initState() { super.initState(); if (widget.isShowLogo != null) { widget.controller?.setMapLogoVisible(widget.isShowLogo!); } if (widget.interactionIsEnabled != null) { widget.controller?.setMapInteractionEnabled(widget.interactionIsEnabled!); } showMarker(); showPolyline(); animateCamera(); } @override Widget build(BuildContext context) { debugPrint( 'MapWidget...build...mapViewType==>$mapViewType,defaultTargetPlatform==>$defaultTargetPlatform'); if (defaultTargetPlatform == TargetPlatform.android) { return PlatformViewLink( surfaceFactory: (context, controller) { return AndroidViewSurface( controller: controller as AndroidViewController, gestureRecognizers: const >{}, hitTestBehavior: PlatformViewHitTestBehavior.opaque, ); }, onCreatePlatformView: onCreatePlatformView, viewType: mapViewType); } else if (defaultTargetPlatform == TargetPlatform.iOS) { return UiKitView( viewType: mapViewType, onPlatformViewCreated: onPlatformViewCreated, creationParamsCodec: const StandardMessageCodec(), ); } return Text('当前平台:$defaultTargetPlatform, 不支持使用地图插件'); } PlatformViewController onCreatePlatformView( PlatformViewCreationParams params) { return PlatformViewsService.initSurfaceAndroidView( id: params.id, viewType: mapViewType, layoutDirection: TextDirection.ltr, creationParams: {}, creationParamsCodec: const StandardMessageCodec(), ) ..addOnPlatformViewCreatedListener(params.onPlatformViewCreated) ..addOnPlatformViewCreatedListener(onPlatformViewCreated) ..create(); } Future onPlatformViewCreated(int viewId) async { MethodChannel mapChannel = MethodChannel('${MapConstants.mapViewChannelName}$viewId'); widget.controller?.setChannel(mapChannel); mapChannel.setMethodCallHandler(_mapMethodCallHandler); } Future _mapMethodCallHandler(MethodCall call) async { debugPrint( '_mapMethodCallHandler...call.method==>${call.method},call.arguments==>${call.arguments}'); switch (call.method) { case MapConstants.methodMarkerOnTap: Map jsonMap = jsonDecode(call.arguments); Marker marker = Marker.fromJson(jsonMap); widget.onMarkerTap?.call(marker); break; } } }