2016-08-19 4 views
1

UPDATE

Ich laufe in ein Problem mit GetMapAsync Nicht Aufruf OnMapReady ich in der Lage bin Überprüfung, den Fehler zu unterdrücken, indem, wenn die Karte null ist die Karte wird dann mit nicht geladen werden benutzerdefinierte Markierungen. Wenn ich dann die Karte leicht verschiebe, wird OnMapReady geladen und die benutzerdefinierten Markierungen werden dann angezeigt. Unten ist meine benutzerdefinierte Renderer-Klasse. Wenn jemand anderes auf dieses Problem gestoßen ist, wäre ich sehr dankbar, dass ich Ihre Lösung hören könnte.Xamarin Forms Karten kundenspezifische Android Renderer GetMapAsync Aufruf OnMapReady Nicht

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using Android.Content; 
using Android.Gms.Maps; 
using Android.Gms.Maps.Model; 
using Android.Views; 
using Android.Widget; 
using BSi.Mobile.Events.Controls; 
using BSi.Mobile.Events.Droid.Renderers; 
using BSi.Mobile.Events.Events; 
using Xamarin.Forms; 
using Xamarin.Forms.Maps; 
using Xamarin.Forms.Maps.Android; 
using View = Xamarin.Forms.View; 

[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))] 
namespace BSi.Mobile.Events.Droid.Renderers 
{ 
    public class CustomMapRenderer : MapRenderer, GoogleMap.IInfoWindowAdapter, IOnMapReadyCallback 
    { 
     GoogleMap map; 
     IList<CustomPin> customPins; 
     private CustomPin selectedPin; 
     bool isDrawn; 

     protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<View> e) 
     { 
      base.OnElementChanged(e); 

      if (e.OldElement != null) 
      { 
       map.InfoWindowClick -= OnInfoWindowClick; 
       map.MarkerClick -= OnMarkerClick; 
       map.MapClick -= OnMapClick; 
      } 

      if (e.NewElement != null) 
      { 
       var formsMap = (CustomMap)e.NewElement; 
       customPins = formsMap.CustomPins; 
       selectedPin = formsMap.SelectedPin; 
       ((MapView)Control).GetMapAsync(this); 
      } 
     } 

     public void OnMapReady(GoogleMap googleMap) 
     { 
      map = googleMap; 
      map.InfoWindowClick += OnInfoWindowClick; 
      map.MarkerClick += OnMarkerClick; 
      map.MapClick += OnMapClick; 
      map.SetInfoWindowAdapter(this); 
      SetMapMarkers(); 
     } 

     private void SetMapMarkers() 
     { 
      map.Clear(); 

      foreach (var pin in customPins) 
      { 
       addMarker(pin, false); 
      } 
      isDrawn = true; 
      if (selectedPin != null) 
      { 
       addMarker(selectedPin, true); 
      } 
     } 

     protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) 
     { 
      base.OnElementPropertyChanged(sender, e); 

      if (e.PropertyName.Equals("VisibleRegion") && !isDrawn && map != null) 
      { 
       SetMapMarkers(); 
      } 
      else if (e.PropertyName.EndsWith("SelectedPin") && map != null) 
      { 
       var customMap = sender as CustomMap; 
       selectedPin = customMap?.SelectedPin; 
       if (selectedPin != null) 
       { 
        addMarker(selectedPin, true); 
       } 
      } 
     } 

     private void addMarker(CustomPin pin, bool isSelected) 
     { 
      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); 
      switch (pin.Id) 
      { 
       case "Convention": 
        marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.star)); 
        break; 
       case "cafe": 
        marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.cafe)); 
        break; 
       case "bar": 
        marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.bar)); 
        break; 
       default: 
        marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.restaurant)); 
        break; 
      } 

      var selectedMarker = map.AddMarker(marker); 

      if (isSelected) 
       selectedMarker.ShowInfoWindow(); 
     } 

     protected override void OnLayout(bool changed, int l, int t, int r, int b) 
     { 
      //Catches Exception incase user needs to update google play services 
      try 
      { 
       base.OnLayout(changed, l, t, r, b); 

       if (changed) 
       { 
        isDrawn = false; 
       } 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.ToString()); 
      } 
     } 

     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 = Android.Net.Uri.Parse(customPin.Url); 
       var intent = new Intent(Intent.ActionView, url); 
       intent.AddFlags(ActivityFlags.NewTask); 
       Android.App.Application.Context.StartActivity(intent); 
      } 
     } 

     public Android.Views.View GetInfoContents(Marker marker) 
     { 
      var inflater = Android.App.Application.Context.GetSystemService(Context.LayoutInflaterService) as LayoutInflater; 
      if (inflater != null) 
      { 
       Android.Views.View view; 

       var customPin = GetCustomPin(marker); 
       if (customPin == null) 
       { 
        throw new Exception("Custom pin not found"); 
       } 

       switch (customPin.Id) 
       { 
        case "Conference": 
         view = inflater.Inflate(Resource.Layout.MapInfoWindow, null); 
         break; 
        default: 
         view = inflater.Inflate(Resource.Layout.MapInfoWindow, null); 
         break; 
       } 

       var infoTitle = view.FindViewById<TextView>(Resource.Id.InfoWindowTitle); 
       var infoSubtitle = view.FindViewById<TextView>(Resource.Id.InfoWindowSubtitle); 
       var infoPhone = view.FindViewById<TextView>(Resource.Id.InfoWindowPhone); 
       var infoWebsite = view.FindViewById<TextView>(Resource.Id.InfoWindowWebsite); 

       if (infoTitle != null) 
       { 
        infoTitle.Text = marker.Title; 
       } 
       else 
       { 
        infoTitle.Visibility = ViewStates.Gone; 
       } 

       if (infoSubtitle != null) 
       { 
        infoSubtitle.Text = marker.Snippet; 
       } 
       else 
       { 
        infoSubtitle.Visibility = ViewStates.Gone; 

       } 

       if (infoPhone != null && customPin.Phone != null) 
       { 
        infoPhone.Text = customPin.Phone; 
       } 
       else 
       { 
        infoPhone.Visibility = ViewStates.Gone; 
       } 

       if (infoWebsite != null && customPin.Url != null) 
       { 
        infoWebsite.Text = customPin.Url; 
       } 
       else 
       { 
        infoWebsite.Visibility = ViewStates.Gone; 
       } 

       return view; 
      } 
      return null; 
     } 

     public Android.Views.View GetInfoWindow(Marker marker) 
     { 
      return null; 
     } 

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

     private void OnMarkerClick(object sender, GoogleMap.MarkerClickEventArgs e) 
     { 
      e.Handled = false; 
      App.EventAggregator?.GetEvent<MapClickedEvent>().Publish(new Pin { Position = new Position(e.Marker.Position.Latitude, e.Marker.Position.Longitude), Label = e.Marker.Title}); 
     } 

     private void OnMapClick(object sender, GoogleMap.MapClickEventArgs e) 
     { 
      App.EventAggregator?.GetEvent<MapClickedEvent>().Publish(null); 
     } 
    } 
} 

Antwort

0

fand ich um eine Arbeit um dieses Problem zu beheben ich den Code bewegte, wo ich Setup die Kartenmarkierungen innerhalb der eigenen Funktion, von dort ich diese Funktion in OnElementPropertyChanged nennen wie bei der normalen Ausführung. Dies richtet die Markierungen ein, wenn sich die Karte bewegt. Um die benutzerdefinierten Markierungen beim Laden der Karte zu laden, habe ich auch Setup-Marker in onMapReady aufgerufen. Mein Code oben spiegelt nun eine funktionierende Lösung wider, ich hoffe, ich habe anderen geholfen, die auf dieses Problem stoßen. Prost!

+0

könnten Sie diesen Code teilen? –

Verwandte Themen