Xamarin Forms - 自定义地图标记不可见
Posted
技术标签:
【中文标题】Xamarin Forms - 自定义地图标记不可见【英文标题】:Xamarin Forms - custom map marker not visible 【发布时间】:2021-10-19 22:08:02 【问题描述】:我正在关注 MS 页面上关于 Custom map renderer 的文章,但我无法让它在 android 上工作。地图显示,但大头针(标记)不存在。我没有发现我所做的与官方文件有什么不同(如上一个链接)。当我调试时,customPins 集合中有 3 个标记。自定义渲染器适用于 UWP。所以问题只存在于 Android 代码中。
这是我用于 Android 的 CustomRender 代码,它不显示图钉。
using System;
using System.Collections.Generic;
using Android.Content;
using Android.Gms.Maps;
using Android.Gms.Maps.Model;
using Android.Widget;
using iVanApp;
using iVanApp.Android.CustomMapRenderers;
using iVanApp.Droid;
using iVanApp.Model;
using Xamarin.Forms;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Maps.Android;
[assembly: ExportRenderer(typeof(NightMap), typeof(MapRenderers))]
namespace iVanApp.Android.CustomMapRenderers
public class MapRenderers : MapRenderer, GoogleMap.IInfoWindowAdapter
List<NightPin> customPins;
public MapRenderers(Context context) : base(context)
protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Map> e)
base.OnElementChanged(e);
if (e.OldElement != null)
NativeMap.InfoWindowClick -= OnInfoWindowClick;
if (e.NewElement != null)
var formsMap = (NightMap)e.NewElement;
customPins = formsMap.NightPins;
protected override void OnMapReady(GoogleMap map)
base.OnMapReady(map);
NativeMap.InfoWindowClick += OnInfoWindowClick;
NativeMap.SetInfoWindowAdapter(this);
protected override MarkerOptions CreateMarker(Pin pin)
var marker = new MarkerOptions();
marker.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
marker.SetTitle(pin.Label);
marker.SetSnippet(pin.Address);
marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.pin));
return marker;
void OnInfoWindowClick(object sender, GoogleMap.InfoWindowClickEventArgs e)
var customPin = GetCustomPin(e.Marker);
if (customPin == null)
throw new Exception("Custom pin not found");
if (!string.IsNullOrWhiteSpace(customPin.Name))
NightPin GetCustomPin(Marker annotation)
var position = new Position(annotation.Position.Latitude, annotation.Position.Longitude);
foreach (var pin in customPins)
if (pin.Position == position)
return pin;
return null;
public global::Android.Views.View GetInfoContents(Marker marker)
var inflater = global::Android.App.Application.Context.GetSystemService(Context.LayoutInflaterService) as global::Android.Views.LayoutInflater;
if (inflater != null)
global::Android.Views.View view;
var customPin = GetCustomPin(marker);
if (customPin == null)
throw new Exception("Custom pin not found");
view = inflater.Inflate(Resource.Layout.mtrl_layout_snackbar_include, null);
if (customPin.Name.Equals("Xamarin"))
view = inflater.Inflate(Resource.Layout.XamarinMapInfoWindow, null);
else
view = inflater.Inflate(Resource.Layout.MapInfoWindow, null);
var infoTitle = view.FindViewById<TextView>(Resource.Id.InfoWindowTitle);
var infoSubtitle = view.FindViewById<TextView>(Resource.Id.InfoWindowSubtitle);
if (infoTitle != null)
infoTitle.Text = marker.Title;
if (infoSubtitle != null)
infoSubtitle.Text = marker.Snippet;
return view;
return null;
public global::Android.Views.View GetInfoWindow(Marker marker)
return null;
有人知道为什么这不起作用吗?
注意:由于出现错误,我不得不修改官方 MS 代码。无论Android.Views.View
在哪里,我都必须将其修改为global::Android.Views.View
,否则会出现以下错误
"'MapRenderers' 没有实现接口成员 'GoogleMap.IInfoWindowAdapter.GetInfoContents(标记)'。 'MapRenderers.GetInfoContents(Marker)' 无法实现 'GoogleMap.IInfoWindowAdapter.GetInfoContents(Marker)' 因为它确实 没有匹配的“视图”返回类型。”。
和
命名空间中不存在类型或命名空间名称“Views” 'iVanApp.Android'(您是否缺少程序集引用?)
希望这不会破坏我的代码。
在调查和阅读其他人的自定义地图问题(主要是解决方案)后,我得到了一个解决方法,即如何在地图上获取图钉,但当我点击图钉(标记)时不显示信息窗口。 Here I found workaround。如果我修改 OnMapReday 并调用和添加方法 SetMapMarkers 则引脚可见,但正如我所说,当我单击引脚时没有显示任何信息窗口
protected override void OnMapReady(GoogleMap map)
base.OnMapReady(map);
NativeMap.InfoWindowClick += OnInfoWindowClick;
NativeMap.SetInfoWindowAdapter(this);
SetMapMarkers();
private void SetMapMarkers()
NativeMap.Clear();
foreach (var pin in customPins)
NativeMap.AddMarker(CreateMarker(pin));
虽然这是一个解决方案,但如果我能在没有这种解决方法的情况下让它工作,我会更喜欢。因此,我没有付出太多努力,为什么单击 pin 时不显示信息窗口。如果没有这种解决方法就没有解决方案,那么我会对有解决方法的解决方案感兴趣,但正如我所说,我不喜欢这样。
【问题讨论】:
在您的旧代码中,我没有看到您在地图上添加图钉是故意的吗?我错过了什么吗? 既然你提到了这一点,我也注意到了。在提供的官方文档和示例中,没有将引脚添加到地图的代码。因此我虽然这不是必需的。并且仅在 UWP 示例中对此进行了调查后,有代码可以将引脚添加到地图。奇怪的是没有Android和ios的代码,还是我遗漏了什么?在我添加代码后,您提到图钉在地图上。因此,如果您将其写为答案,我可以将其标记为正确的答案。 【参考方案1】:正如 FreakyAli 所说,为 CustomMap 添加自定义图钉和位置。
<local:CustomMap x:Name="customMap" MapType="Street" />
添加自定义图钉并使用 MoveToRegion 方法定位地图视图
public MainPage()
InitializeComponent();
var pin = new CustomPin
Type = PinType.Place,
Position = new Position(37.79752, -122.40183),
Label = "Xamarin San Francisco Office",
Address = "394 Pacific Ave, San Francisco CA",
Id = "Xamarin",
Url = "http://xamarin.com/about/"
;
customMap.CustomPins = new List<CustomPin> pin ;
customMap.Pins.Add(pin);
customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(37.79752, -122.40183), Distance.FromMiles(1.0)));
我可以通过点击地图图钉获得InfoWindow,没有问题。
【讨论】:
以上是关于Xamarin Forms - 自定义地图标记不可见的主要内容,如果未能解决你的问题,请参考以下文章
如何居中/设置地图缩放以覆盖 Xamarin.Forms 上可见的所有标记?
如何在 Xamarin Forms 中实现标记聚类(谷歌地图)
Xamarin.Forms 不可点击的 ListView(移除选择涟漪效应)