2016-08-19 1 views
1

UPDATE

Я бегу в проблему с GetMapAsync Не называя OnMapReady Я могу подавить ошибку, проверяя, если карта является недействительным карта будет загружать с не пользовательские маркеры. Если я затем перемещу карту немного, OnMapReady будет загружаться, и тогда будут отображаться пользовательские маркеры. Ниже мой собственный класс рендеринга, если кто-то еще столкнулся с этой проблемой, я был бы очень благодарен за ваше разрешение.Xamarin Формы Карты Пользовательские Android Renderer GetMapAsync Не Calling OnMapReady

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

ответ

0

Я нашел работу вокруг, чтобы решить эту проблему, я переехал код, где я установка маркеров карты внутри своей собственной функции, оттуда я называю эту функцию внутри OnElementPropertyChanged, как с обычным исполнением. Это устанавливает маркеры при перемещении карты. Чтобы загрузить пользовательские маркеры при загрузке карты, я также назвал маркеры установки внутри onMapReady. Теперь мой код выше отражает рабочее решение, я надеюсь, что помог кому-то еще, кто может столкнуться с этим вопросом. Cheers!

+0

Можете ли вы поделиться этим кодом? –