简体   繁体   中英

How change xamarin.forms.maps marker with icon in Android

I want to change the current marker on xamarin.forms.maps with icon.

On my project I create CustomMap.cs class and CustomPin.cs class with this code:

using System;
using System.Collections.Generic;
using Xamarin.Forms.Maps;

namespace MaritsaTundzhaForecast
{
    public class CustomMap : Map
    {
        public List<CustomPin> CustomPins { get; set; }
    }
}

using System;
using Xamarin.Forms.Maps;

namespace MaritsaTundzhaForecast
{
    public class CustomPin : Pin
    {
        public string Name { get; set; }
        public string Url { get; set; }
    }
}

After that I set the map on xaml page with this code:

 <Grid>
  <Label Text="Forecast Maritza-Tundzha"
         HorizontalOptions="CenterAndExpand"
         FontSize="Large"
         FontAttributes="Bold"/>
    <Grid Margin="0,30,0,10">
        <Grid.RowDefinitions>
            <RowDefinition Height="400" />
        </Grid.RowDefinitions>

      <local:CustomMap x:Name="customMap"
               MapType="Street" />
    </Grid>
</Grid>

In the same xaml page in the cs file I set marker on the map with this code:

 public MainPage()
    {
        InitializeComponent();

        CustomPin pin = new CustomPin
        {
            Type = PinType.Place,
            Position = new Position(37.79752, -122.40183),
            Label = "Xamarin San Francisco Office",
            Address = "394 Pacific Ave, San Francisco CA",
            Name = "Xamarin",
            Url = "http://xamarin.com/about/"
        };
        customMap.CustomPins = new List<CustomPin> { pin };
        customMap.Pins.Add(pin);
        customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(37.79752, -122.40183), Distance.FromMiles(1.0)));
    }

Now I read this example and I don't know how to use this code from the example in my way:

    protected override MarkerOptions CreateMarker(Pin pin)
{
    var marker = new MarkerOptions();
    marker.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
    marker.SetTitle(pin.Label);
    marker.SetSnippet(pin.Address);
    marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.pin));
    return marker;
}

So I set the icon in drawable folder. What can I change from this code to use different icons and whether there is a need to change the code in another class?

Аll day I try to replace the standard icon with another icon and fail.

Like jason said there is complete sample app in the link you provided. Sample map app

You need to create a custom map renderer in your android project folder like this. Create a class named CustomMapRenderer

[assembly: ExportRenderer(typeof(CustomMap),typeof(CustomMapRenderer))]
    namespace CustomRenderer.Droid
    {
        public class CustomMapRenderer : MapRenderer, GoogleMap.IInfoWindowAdapter
        {
            List<CustomPin> customPins;
    
            public CustomMapRenderer(Context context) : base(context)
            {
            }
    
            protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Map> e)
            {
                base.OnElementChanged(e);
    
                if (e.OldElement != null)
                {
                    NativeMap.InfoWindowClick -= OnInfoWindowClick;
                }
    
                if (e.NewElement != null)
                {
                    var formsMap = (CustomMap)e.NewElement;
                    customPins = formsMap.CustomPins;
                }
            }
    
            protected override void OnMapReady(GoogleMap map)
            {
                base.OnMapReady(map);
    
                NativeMap.InfoWindowClick += OnInfoWindowClick;
                NativeMap.SetInfoWindowAdapter(this);
            }
    
            protected override MarkerOptions CreateMarker(Pin pin)
            {
                var marker = new MarkerOptions();
                marker.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
                marker.SetTitle(pin.Label);
                marker.SetSnippet(pin.Address);
                marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.pin));
                return marker;
            }
    
            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 Android.Views.LayoutInflater;
                if (inflater != null)
                {
                    Android.Views.View view;
    
                    var customPin = GetCustomPin(marker);
                    if (customPin == null)
                    {
                        throw new Exception("Custom pin not found");
                    }
    
                    if (customPin.Name.Equals("Xamarin"))
                    {
                        view = inflater.Inflate(Resource.Layout.XamarinMapInfoWindow, null);
                    }
                    else
                    {
                        view = inflater.Inflate(Resource.Layout.MapInfoWindow, null);
                    }
    
                    var infoTitle = view.FindViewById<TextView>(Resource.Id.InfoWindowTitle);
                    var infoSubtitle = view.FindViewById<TextView>(Resource.Id.InfoWindowSubtitle);
    
                    if (infoTitle != null)
                    {
                        infoTitle.Text = marker.Title;
                    }
                    if (infoSubtitle != null)
                    {
                        infoSubtitle.Text = marker.Snippet;
                    }
    
                    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.Position == position)
                    {
                        return pin;
                    }
                }
                return null;
            }
        }
    }

As you can see the code portion which you mentioned in this render. You can change the icon here

    protected override MarkerOptions CreateMarker(Pin pin)
    {
        var marker = new MarkerOptions();
        marker.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
        marker.SetTitle(pin.Label);
        marker.SetSnippet(pin.Address);

///<---- Change icon here--->
        marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.pin));
        return marker;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM