【问题标题】:How change xamarin.forms.maps marker with icon in Android如何在 Android 中使用图标更改 xamarin.forms.maps 标记
【发布时间】:2021-05-29 14:51:11
【问题描述】:

我想用图标更改xamarin.forms.maps 上的当前标记。

在我的项目中,我使用以下代码创建 CustomMap.cs 类和 CustomPin.cs 类:

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

之后,我使用以下代码在 xaml 页面上设置地图:

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

在 cs 文件的同一个 xaml 页面中,我使用以下代码在地图上设置了标记:

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

现在我读到了这个example,但我不知道如何以我的方式使用示例中的这段代码:

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

所以我将图标设置在drawable 文件夹中。我可以从这段代码中更改什么以使用不同的图标以及是否需要更改另一个类中的代码?

我整天都在尝试用另一个图标替换标准图标但失败了。

【问题讨论】:

  • 您发布的链接有一个完整的示例应用程序,可以完全满足您的需求。您是否尝试过运行示例?

标签: c# xamarin xamarin.forms maps


【解决方案1】:

就像 jason 所说,您提供的链接中有完整的示例应用程序。Sample map app

您需要像这样在您的 android 项目文件夹中创建自定义地图渲染器。创建一个名为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;
            }
        }
    }

您可以看到您在此渲染中提到的代码部分。您可以在此处更改图标

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

【讨论】:

  • Resource.Layout.MapInfoWindow Resource.Id.InfoWindowTitle Resource.Id.InfoWindowSubtitle 我收到此错误:“Resource.Layout”不包含“XamarinMapInfoWindow”的定义???
  • 您是否也将 xamarin map nuget 添加到了 android?
  • 我的 android 项目中有 xamarin.forms.maps 库,但我认为 XamarinMapInfoWindow 和 recurce.designer.cs 中缺少其他元素。所以我得到了他们的更正,但是当我点击标记出现我无法解决的错误。你能在这里查看我的其他问题吗:stackoverflow.com/questions/67759807/…
猜你喜欢
  • 2021-12-04
  • 1970-01-01
  • 2015-08-30
  • 1970-01-01
  • 2013-08-31
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
  • 1970-01-01
相关资源
最近更新 更多