1

Я создал карту с пользовательским маркером с обновлением местоположения в реальном времени. Но после добавления нового вывода на карту его не применяли пользовательский рендерер. Если я увеличил или уменьшил масштаб на карте, то применил бы это для рендеринга маркеров. Вот мой код.Не освежающий пользовательский рендерер Xamarin forms maps

Этот код находится в проекте Xamarin.Droid

 public class CustomMapRenderer : MapRenderer, IOnMapReadyCallback, GoogleMap.IInfoWindowAdapter 
{ 

    GoogleMap map; 
    List<Position> routeCoordinates; 
    List<CustomPin> customPins; 
    Action<CustomPin> onInfoWindowClicked; 


    public void OnMapReady(GoogleMap googleMap) 
    { 
     map = googleMap; 

     //map.InfoWindowClick += OnInfoWindowClick; 
     map.SetInfoWindowAdapter(this); 

     var polylineOptions = new PolylineOptions(); 
     polylineOptions.InvokeColor(Android.Graphics.Color.Blue); 

     foreach (var position in routeCoordinates) 
     { 
      polylineOptions.Add(new LatLng(position.Latitude, position.Longitude)); 
     } 

     map.AddPolyline(polylineOptions); 

    } 

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

     if (e.OldElement != null) 
     { 
      map.InfoWindowClick -= OnInfoWindowClick; 
      // Unsubscribe 
     } 

     if (e.NewElement != null) 
     { 

      var formsMap = (CustomMap)e.NewElement; 

      routeCoordinates = formsMap.RouteCoordinates; 
      customPins = formsMap.CustomPins; 
      onInfoWindowClicked = formsMap.OnInfoWindowClicked; 
      ((Android.Gms.Maps.MapView)Control).GetMapAsync(this); 
     } 
    } 

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

     if (map != null) 
     { 
      map.Clear(); 

      foreach (var pin in customPins) 
      { 
       var marker = new MarkerOptions(); 
       marker.SetPosition(new LatLng(pin.Pin.Position.Latitude, pin.Pin.Position.Longitude)); 
       marker.SetTitle(pin.Id.ToString()); 
       marker.SetSnippet(pin.Pin.Address); 

       if(pin.UserType == global::Common.Models.UserType.Driver) 
       { 
        marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.car)); 
       } 

       else if (pin.UserType == global::Common.Models.UserType.Rider) 
       { 
        marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.person)); 
       } 

       map.AddMarker(marker); 
      } 

     } 
    } 

    void OnInfoWindowClick(object sender, GoogleMap.InfoWindowClickEventArgs e) 
    { 
     onInfoWindowClicked(GetCustomPin(e.Marker)); 
    } 

    private CustomPin GetCustomPin(Marker marker) 
    { 
     return customPins.Find(x => x.Id.ToString() ==marker.Title.ToString()); 
    } 

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

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

      view = inflater.Inflate(Resource.Layout.MapInfoWindow, null); 

      var infoImage = view.FindViewById<ImageView>(Resource.Id.markerInfoImage); 
      var infoTitle = view.FindViewById<TextView>(Resource.Id.markerInfoTitle); 
      var infoSummary = view.FindViewById<TextView>(Resource.Id.markerInfoSummary); 



      System.IO.Stream ims = Context.Assets.Open(customPin.Image); 

      // load image as Drawable 
      Drawable d = Drawable.CreateFromStream(ims, null); 

      // set image to ImageView 
      infoImage.SetImageDrawable(d); 


      //File file = new File(customPin.Image); 
      //var image = Android.Net.Uri.FromFile(file); 
      //var resource=ResourceManager.GetDrawableByName("driverLogActive_icon.png"); 
      //infoImage.SetImageResource(resource); 
      //infoImag = customPin.Title; 

      infoTitle.Text = customPin.Title; 

      infoSummary.Text = customPin.MobileNo; 

      return view; 
     } 
     return null; 
    } 

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

Этот код находится в Xamarin.Forms проект

public class CustomPin 
{ 
    public Pin Pin { get; set; } 
    public Guid Id { get; set; } 
    public string Title { get; set; } 
    public string MobileNo { get; set; } 
    public string Image { get; set; } 
    public string UserName { get; set; } 
    public UserType UserType { get; set; } 
} 

public class CustomMap : Map 
{ 
    public static readonly BindableProperty RouteCoordinatesProperty = BindableProperty.Create(nameof(RouteCoordinates), typeof(List<Position>), typeof(CustomMap), new List<Position>(), BindingMode.TwoWay); 
    public static readonly BindableProperty CustomPinsProperty = BindableProperty.Create(nameof(CustomPins), typeof(List<CustomPin>), typeof(CustomMap), new List<CustomPin>(), BindingMode.TwoWay); 



    public List<CustomPin> CustomPins 
    { 
     get { return (List<CustomPin>)GetValue(CustomPinsProperty); } 
     set { SetValue(CustomPinsProperty, value); } 
    } 

    public List<Position> RouteCoordinates 
    { 
     get { return (List<Position>)GetValue(RouteCoordinatesProperty); } 
     set { SetValue(RouteCoordinatesProperty, value); } 
    } 

    public Action<CustomPin> OnInfoWindowClicked; 

    public CustomMap() 
    { 
     RouteCoordinates = new List<Position>(); 
     CustomPins = new List<CustomPin>(); 
    } 
} 

Это как я использую пользовательскую карту для визуализации булавки в проекте Xamrin.Fomrs

private void RenderPin(string longitudeCoordinate, string latitudeCoordinate,bool canMoveToLoacation, string lable,UserType userType,string mobileNo,string image,string userName) 
    { 
     double latitude = 0; 
     double longitude = 0; 

     double.TryParse(latitudeCoordinate, out latitude); 
     double.TryParse(longitudeCoordinate, out longitude); 

     var position = new Position(latitude, longitude); 

     var pin = new CustomPin 
     { 
      Pin = new Pin 
      { 
       Type = PinType.Place, 
       Position = position, 
       Label = lable, 
      }, 
      Title = lable, 
      UserType = userType, 
      MobileNo = "Mobile No:" + mobileNo, 
      Image = "profile_images/" + image, 
      UserName = userName, 
      Id = Guid.NewGuid() 
     }; 


     map.CustomPins.Add(pin); 
     map.Pins.Add(pin.Pin); 
     if (canMoveToLoacation) 
     { 
      map.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(latitude, longitude), Distance.FromKilometers(2))); 
     } 
    } 

ответ

0

Если установить Xamarin.Forms.Maps пре-релиз (2.3.5.255-pre5), вы можете теперь просто переопределите метод CreateMarker() в MapRenderer. Он намного более изящный, и он исправляет эту проблему, когда булавки не обновляются при добавлении после создания карты.

Смежные вопросы