【发布时间】: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的代码,还是我遗漏了什么?在我添加代码后,您提到图钉在地图上。因此,如果您将其写为答案,我可以将其标记为正确的答案。
标签: google-maps xamarin xamarin.forms custom-renderer