You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin Forms Android端自定义地图标记(Marker)不显示问题求助

根因分析

不使用workaround时标记不显示的原因

  • Xamarin.Forms 原生的MapRenderer只会自动渲染基类Map自带的Pins集合中的元素,你自定义的NightMap.NightPins属于自定义集合,没有纳入原生渲染器的自动渲染流程,所以哪怕customPins里有数据也不会自动生成Marker。
  • 你之前修改的global::Android.Views.View命名空间前缀只是解决命名空间冲突,和标记不显示没有关联。

使用workaround后信息窗口不显示的原因

  • 你通过坐标匹配NightPin的逻辑存在精度问题:经纬度是double类型,存储和渲染时的微小精度误差会导致GetCustomPin返回null,触发异常后信息窗口无法正常加载。
  • 你GetInfoContents方法中第一行多余加载了mtrl_layout_snackbar_include布局,后续才覆盖为实际的信息窗口布局,可能存在布局加载异常。
  • 部分场景下手动添加的Marker不会默认触发信息窗口弹出逻辑,需要手动处理点击事件。

解决方案

方案1:无需workaround的标准实现(推荐)

  1. 调整自定义NightMap的逻辑,将NightPins改为ObservableCollection<NightPin>类型,监听集合变化,同步将元素同步到基类Map.Pins集合,触发原生自动渲染:
public class NightMap : Map
{
    public ObservableCollection<NightPin> NightPins { get; } = new ObservableCollection<NightPin>();

    public NightMap()
    {
        NightPins.CollectionChanged += (s, e) =>
        {
            if (e.NewItems != null)
            {
                foreach (NightPin pin in e.NewItems)
                {
                    Pins.Add(pin);
                }
            }
            if (e.OldItems != null)
            {
                foreach (NightPin pin in e.OldItems)
                {
                    Pins.Remove(pin);
                }
            }
        };
    }
}
  1. 确保NightPin直接继承自Xamarin.Forms.Maps.Pin,保证类型兼容。
  2. 删掉你新增的SetMapMarkers方法和调用逻辑,原生渲染器会自动调用你重写的CreateMarker方法生成自定义标记,同时信息窗口逻辑也会正常生效。

方案2:修复现有workaround的信息窗口问题

如果要保留手动添加Marker的逻辑,按以下步骤修改:

  1. 新增Marker映射字典,替换坐标匹配逻辑,避免精度问题:
private Dictionary<Marker, NightPin> _markerLookup = new Dictionary<Marker, NightPin>();

private void SetMapMarkers()
{
    NativeMap.Clear();
    _markerLookup.Clear();
    foreach (var pin in customPins)
    {
        var marker = NativeMap.AddMarker(CreateMarker(pin));
        _markerLookup.Add(marker, pin);
    }
}

NightPin GetCustomPin(Marker annotation)
{
    _markerLookup.TryGetValue(annotation, out var pin);
    return pin;
}
  1. 删掉GetInfoContents方法中多余的布局加载代码:
// 删掉这行多余代码
// view = inflater.Inflate(Resource.Layout.mtrl_layout_snackbar_include, null);
  1. 监听Marker点击事件,手动弹出信息窗口:
protected override void OnMapReady(GoogleMap map)
{
    base.OnMapReady(map);
    NativeMap.InfoWindowClick += OnInfoWindowClick;
    NativeMap.SetInfoWindowAdapter(this);
    // 新增Marker点击监听
    NativeMap.MarkerClick += (s, e) => 
    {
        e.Marker.ShowInfoWindow();
        e.Handled = true;
    };
    SetMapMarkers();
}
  1. 确保所有NightPin的Label和Address属性都已赋值,谷歌地图默认不会为空内容的Marker弹出信息窗口。

内容的提问来源于stack exchange,提问作者Bumbar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 08:48:04