MAUI Map Control:无需点击Pin默认显示Google Map API商家名称
.NET 6/.NET 7下实现Google Map Pin自动显示商家名称
解决思路
官方的Google Maps控件在.NET 6/7里没有直接提供Pin自动弹出信息窗口的功能,得靠调用Android原生SDK的方法实现——不管是.NET MAUI还是Xamarin.Forms,都需要写个自定义处理器/渲染器,在Pin添加到地图时主动触发信息窗口显示。
.NET MAUI(.NET 6/7)实现步骤
1. 编写自定义Map Handler
创建继承自MapHandler的类,监听地图加载完成事件,处理Pin的自动显示逻辑:
using Microsoft.Maui.Maps.Handlers; using Android.Gms.Maps; using Android.Gms.Maps.Model; namespace 你的应用命名空间.Platforms.Android; public class CustomMapHandler : MapHandler { protected override void ConnectHandler(MapView platformView) { base.ConnectHandler(platformView); if (PlatformView.Map != null) { PlatformView.Map.MapReady += OnMapReady; } } private void OnMapReady(object sender, GoogleMapEventArgs e) { var googleMap = e.GoogleMap; // 显示已加载的Pin信息窗口 foreach (var pin in MauiElement.Pins) { ShowPinInfoWindow(pin, googleMap); } // 监听Pin集合变化,新添加的Pin自动显示信息窗口 MauiElement.Pins.CollectionChanged += (s, args) => { if (args.NewItems != null) { foreach (var newPin in args.NewItems) { if (newPin is Microsoft.Maui.Maps.Pin pin) { ShowPinInfoWindow(pin, googleMap); } } } }; } private void ShowPinInfoWindow(Microsoft.Maui.Maps.Pin pin, GoogleMap googleMap) { // 获取对应原生Marker对象 if (Handler.MauiContext?.GetMarker(pin) is Marker nativeMarker) { // 主动弹出信息窗口 googleMap.ShowInfoWindow(nativeMarker); } } }
2. 注册自定义Handler
在MauiProgram.cs中注册自定义Handler,让应用使用该处理器渲染地图:
using 你的应用命名空间.Platforms.Android; builder.ConfigureMauiHandlers(handlers => { #if ANDROID handlers.AddHandler<Microsoft.Maui.Maps.Map, CustomMapHandler>(); #endif });
Xamarin.Forms(.NET 6)实现步骤
1. 编写自定义Map渲染器
在Android项目中创建继承自MapRenderer的渲染器,实现IOnMapReadyCallback接口:
using Xamarin.Forms.Maps; using Xamarin.Forms.Maps.Android; using Android.Gms.Maps; using Android.Gms.Maps.Model; using 你的应用命名空间.Droid; [assembly: ExportRenderer(typeof(Map), typeof(CustomMapRenderer))] namespace 你的应用命名空间.Droid; public class CustomMapRenderer : MapRenderer, IOnMapReadyCallback { private GoogleMap _googleMap; protected override void OnElementChanged(ElementChangedEventArgs<Map> e) { base.OnElementChanged(e); if (e.OldElement != null) { ((MapView)Control).GetMapAsync(this).Dispose(); } if (e.NewElement != null) { ((MapView)Control).GetMapAsync(this); } } public void OnMapReady(GoogleMap googleMap) { _googleMap = googleMap; // 显示已加载的Pin信息窗口 foreach (var pin in Element.Pins) { ShowPinInfo(pin); } // 监听Pin集合变化,新添加的Pin自动显示 Element.Pins.CollectionChanged += Pins_CollectionChanged; } private void Pins_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { if (e.NewItems != null && _googleMap != null) { foreach (Pin pin in e.NewItems) { ShowPinInfo(pin); } } } private void ShowPinInfo(Pin pin) { var marker = GetNativeMarker(pin); if (marker != null) { _googleMap.ShowInfoWindow(marker); } } private Marker GetNativeMarker(Pin pin) { // 通过Pin的标签和地址匹配原生Marker if (NativeMap != null) { foreach (var marker in NativeMap.Markers) { if (marker.Title == pin.Label && marker.Snippet == pin.Address) { return marker; } } } return null; } }
注意事项
- 你的Pin必须提前设置好
Label(商家名称)和Address(可选),原生信息窗口默认会展示这两个内容。 - 如果不满意默认信息窗口样式,可以通过
googleMap.SetInfoWindowAdapter编写自定义布局替换。 - 动态添加Pin时,要确保Pin已经加入到Map的Pins集合后再调用显示方法,否则无法获取到原生Marker对象。
内容的提问来源于stack exchange,提问作者Ron
相关产品推荐
相关产品推荐

