设置自定义标记图像会覆盖默认标记图标以及自定义图标
将表单版本更新到2.4.0.282后,我开始在MapView
中收到这种奇怪的行为。我已经创建了一个自定义渲染器,用于android中的地图,并根据需要设置标记图像。自定义标记实际上会出现,但在其上方,它的默认图标仍然会被覆盖。设置自定义标记图像会覆盖默认标记图标以及自定义图标
请注意,我使用Xamarin.Maps版本2.4.0.282,试图降级到以前的版本,但我没有任何帮助。
我甚至尝试过了通过注释线,
Forms.SetFlags( “FastRenderers_Experimental”);
但即使这并没有帮助。
下面是我创建的渲染,
public class CustomMapRenderer : MapRenderer, IOnMapReadyCallback
{
GoogleMap map;
public static double PreviousDistance = 0;
List<CustomPin> customPins;
CustomMap formsMap = null;
protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Map> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
map.InfoWindowClick -= OnInfoWindowClick;
map.MarkerClick -= OnMarkerClick;
}
if (e.NewElement != null)
{
formsMap = (CustomMap)e.NewElement;
customPins = formsMap.CustomPins;
((MapView)Control).GetMapAsync(this);
}
}
protected override void OnMapReady(GoogleMap googleMap)
{
map = googleMap;
map.InfoWindowClick += OnInfoWindowClick;
map.MarkerClick += OnMarkerClick;
map.UiSettings.ZoomControlsEnabled = false;
formsMap.MoveToRegion(MapSpan.FromCenterAndRadius(formsMap.Location, Distance.FromMiles(1.0)));
if(customPins != null && customPins.Count > 0)
{
setMapPins("CustomPins");
}
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == "CustomPins" || (e.PropertyName.Equals("VisibleRegion")))
{
setMapPins(e.PropertyName);
}
}
private void setMapPins(string PropertyName)
{
customPins = formsMap.CustomPins;
map.Clear();
if (customPins != null && customPins.Count > 0)
{
if (PropertyName == "CustomPins")
{
//Set map zoom
var defaultZoom = 14;
try
{
PreviousDistance = DistanceCalculation.MoveToRegionData.MoveToRegion(formsMap, customPins, defaultZoom, PreviousDistance);
}
catch (Exception ex)
{
PreviousDistance = 0;
Console.WriteLine(ex.Message);
}
}
foreach (var pin in customPins)
{
var pinImage = Resources.GetIdentifier(pin.PinImage.ToLower(), "drawable", Context.PackageName);
var markerImg = BitmapDescriptorFactory.FromResource(pinImage);
map.AddMarker(new MarkerOptions().SetTitle(pin.Pin.Label).SetSnippet(pin.Id).SetPosition(new LatLng(pin.Pin.Position.Latitude, pin.Pin.Position.Longitude)).SetIcon(markerImg));
}
}
else
{
Console.WriteLine("In else!!");
}
}
protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
base.OnLayout(changed, l, t, r, b);
if (changed)
{
}
}
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.Url))
{
var url = global::Android.Net.Uri.Parse(customPin.Url);
var intent = new Intent(Intent.ActionView, url);
intent.AddFlags(ActivityFlags.NewTask);
global::Android.App.Application.Context.StartActivity(intent);
}
}
CustomPin GetCustomPin(Marker annotation)
{
var position = new Position(annotation.Position.Latitude, annotation.Position.Longitude);
foreach (var pin in customPins)
{
if (pin.Pin.Position == position)
{
return pin;
}
}
return null;
}
void OnMarkerClick(object sender, GoogleMap.MarkerClickEventArgs ea)
{
var marker = (Marker) ea.Marker;
formsMap.IsPinClicked = false;
var customPin = GetCustomPin(marker);
if (customPin == null)
{
throw new Exception("Custom pin not found");
}
formsMap.SelectedPinId = Convert.ToInt32(marker.Snippet);
formsMap.IsPinClicked = true;
}
}
这是它看起来像现在..
我已经创建了一个地图android系统,其中定制呈现我按照我的要求设置标记图像。自定义标记实际上会出现,但在其上方,它的默认图标仍然会被覆盖。
我做了一个演示和转载问题,经过一些测试,我发现重写OnMapReady
函数会导致问题。即使完全清空OnMapReady
问题也会发生。我的猜测是在自定义地图渲染中调用OnMapReady
可能导致包含引脚的地图重新渲染。
解决方案:
- 评论
OnMapReady
出来。 - 将
OnMapReady
中的逻辑移至OnElementChanged
。 - 让你的本地变量
map=NativeMap
并确保setMapPins
被调用OnElementPropertyChanged
。
那太棒了。在阅读您的解决方案时,我在代码中做了一些更改,注释掉了OnMapReady,并在OnElementPropertyChanged中进行了更改。很少有快速检查显示引脚被绘制时,默认引脚闪烁几秒钟然后消失,但它以任何方式达到目的。非常感谢。你救我:-) –
Add NativeMap.Clear();在OnElementPropertyChanged并再试一次。希望它会帮助!
查看下面的代码来定制Android平台上的PIN。
[assembly:ExportRenderer (typeof(CustomMap), typeof(CustomMapRenderer))]
namespace CustomRenderer.Droid
{
public class CustomMapRenderer : MapRenderer, GoogleMap.IInfoWindowAdapter
{
List<CustomPin> customPins;
bool isDrawn;
protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<View> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
NativeMap.InfoWindowClick -= OnInfoWindowClick;
}
if (e.NewElement != null)
{
var formsMap = (CustomMap)e.NewElement;
customPins = formsMap.CustomPins;
((MapView)Control).GetMapAsync(this);
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName.Equals("VisibleRegion") && !isDrawn)
{
NativeMap.Clear();
NativeMap.InfoWindowClick += OnInfoWindowClick;
NativeMap.SetInfoWindowAdapter(this);
foreach (var pin in customPins)
{
var marker = new MarkerOptions();
marker.SetPosition(new LatLng(pin.Pin.Position.Latitude, pin.Pin.Position.Longitude));
marker.SetTitle(pin.Pin.Label);
marker.SetSnippet(pin.Pin.Address);
marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.pin));
NativeMap.AddMarker(marker);
}
isDrawn = true;
}
}
}
}
更多细节Click here
是的,我应用了相同的解决方案,它似乎按照我的预期工作。感谢您提供解决方案的努力。谢谢 :-) –
你清除本地地图添加新的图标之前?请你能提供详细的代码或基本的演示程序,可以重现问题吗? –
@ ElvisXia-MSFT,是的。我也编辑了我的文章。希望这可以帮助你找出问题。 –