Xamarin Forms - 自定义地图标记不可见

Xamarin Forms - custom map marker not visible

我正在关注 MS 页面上关于 Custom map renderer 的文章,但我无法让它在 android 上工作。地图显示但图钉(标记)不存在。我没有发现我所做的与官方文档有什么不同(如前link)。当我调试时,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' does not implement interface member 'GoogleMap.IInfoWindowAdapter.GetInfoContents(Marker)'. 'MapRenderers.GetInfoContents(Marker)' cannot implement 'GoogleMap.IInfoWindowAdapter.GetInfoContents(Marker)' because it does not have the matching return type of 'View'.".

The type or namespace name 'Views' does not exist in the namespace 'iVanApp.Android' (are you missing an assembly reference?)

希望这没有破坏我的代码。

在调查和阅读其他人的自定义地图问题(以及主要解决方案)后,我得到了一个变通解决方案如何在地图上获取图钉,但在我单击图钉(标记)时不显示信息 window。 。如果我修改 OnMapReday 并调用和添加方法 SetMapMarkers,则引脚可见,但正如我所说,当我单击引脚

时,不会显示任何信息 window
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 时没有显示信息 window。如果没有这个变通办法就没有解决方案,那么我会对有变通办法的解决方案感兴趣,但正如我所说,我不喜欢这样做。

正如 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)));

    }

我可以通过点击地图图钉来获取信息窗口,没问题。