2017-10-13 9 views
0

Après la mise à jour de la version des formulaires vers la version 2.4.0.282, j'ai commencé à obtenir ce comportement étrange dans MapView. J'ai créé un moteur de rendu personnalisé pour la carte dans Android où je suis en train de définir des images de marqueurs selon mes besoins. En fait, les marqueurs personnalisés apparaissent, mais en plus, leur icône par défaut est toujours surchargée.La définition de l'image du marqueur personnalisé recouvrirait l'icône du marqueur par défaut avec l'icône personnalisée

Notez que j'utilise Xamarin.Maps version 2.4.0.282, j'ai essayé de rétrograder à des versions antérieures, mais je ne suis d'aucune aide.

Je ont même essayé par la ligne des commentaires,

Forms.SetFlags ("FastRenderers_Experimental");

mais même cela n'a pas aidé.

Ci-dessous est le moteur de rendu que j'ai créé,

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; 
     } 
    } 

C'est ce qu'il ressemble à ce moment ..

enter image description here

+0

Est-ce que vous ne videz pas la carte d'origine avant d'ajouter de nouvelles icônes? Et s'il vous plaît pourriez-vous fournir des codes détaillés ou une démo de base qui peut reproduire le problème? –

+0

@ ElvisXia-MSFT, Oui je l'ai fait. J'ai aussi édité mon post. J'espère que cela vous aidera à comprendre le problème. –

Répondre

0

J'ai créé un moteur de rendu personnalisé pour carte dans android où Je suis en train de définir des images de marqueurs selon mes besoins. En fait, les marqueurs personnalisés apparaissent, mais en plus, leur icône par défaut est toujours surchargée.

J'ai fait une démonstration et reproduit le problème, après quelques tests, je trouve que la fonction primordiale de OnMapReady provoque le problème. Même avec OnMapReady totalement vide le problème se produira. Ma conjecture est un appel à la OnMapReady dans la carte personnalisée Render pourrait conduire à un rerender de la carte, y compris les épingles.

Solution:

  1. Commentaire OnMapReady out.
  2. Déplacez la logique dans OnMapReady à OnElementChanged.
  3. Laissez votre variable locale map=NativeMap et assurez-vous que setMapPins est appelée OnElementPropertyChanged.
+0

Eh bien c'est génial.En lisant votre solution, j'ai fait quelques changements dans mon code, a commenté OnMapReady, fait des changements dans OnElementPropertyChanged. Peu de vérifications rapides montrent quand les épingles sont en train d'être dessinées, les épingles par défaut clignotent pendant une fraction de seconde, puis disparaissent, mais cela ne sert à rien. Merci beaucoup. Vous me sauvez :-) –

0

Ajouter NativeMap.Clear(); dans OnElementPropertyChanged et réessayez. J'espère que cela aidera !!!

Jetez un oeil ci-dessous le code pour la personnalisation de broche sur la plate-forme Android.

[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; 
      } 
     } 
    } 

} 

Pour plus de détails Click here

+0

Oui, j'ai appliqué une solution identique et il semble fonctionner selon mes attentes. Appréciez vos efforts pour fournir la solution. Merci :-) –