2017-10-13 160 views
0

将表单版本更新到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; 
     } 
    } 

这是它看起来像现在..

enter image description here

+0

你清除本地地图添加新的图标之前?请你能提供详细的代码或基本的演示程序,可以重现问题吗? –

+0

@ ElvisXia-MSFT,是的。我也编辑了我的文章。希望这可以帮助你找出问题。 –

回答

0

我已经创建了一个地图android系统,其中定制呈现我按照我的要求设置标记图像。自定义标记实际上会出现,但在其上方,它的默认图标仍然会被覆盖。

我做了一个演示和转载问题,经过一些测试,我发现重写OnMapReady函数会导致问题。即使完全清空OnMapReady问题也会发生。我的猜测是在自定义地图渲染中调用OnMapReady可能导致包含引脚的地图重新渲染。

解决方案:

  1. 评论OnMapReady出来。
  2. OnMapReady中的逻辑移至OnElementChanged
  3. 让你的本地变量map=NativeMap并确保setMapPins被调用OnElementPropertyChanged
+0

那太棒了。在阅读您的解决方案时,我在代码中做了一些更改,注释掉了OnMapReady,并在OnElementPropertyChanged中进行了更改。很少有快速检查显示引脚被绘制时,默认引脚闪烁几秒钟然后消失,但它以任何方式达到目的。非常感谢。你救我:-) –

0

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

+0

是的,我应用了相同的解决方案,它似乎按照我的预期工作。感谢您提供解决方案的努力。谢谢 :-) –

相关问题