Share via


Xamarin.Forms Pins de mapa

O Xamarin.FormsMap controle permite que os locais sejam marcados com Pin objetos. A Pin é um marcador de mapa que abre uma janela de informações quando tocado:

Captura de tela de um pino de mapa e sua janela de informações, no iOS e Android

Quando um Pin objeto é adicionado à Map.Pins coleção, o pino é renderizado no mapa.

A classe Pin tem as propriedades a seguir:

  • Address, do tipo string, que normalmente representa o endereço do local do pino. No entanto, pode ser qualquer string conteúdo, não apenas um endereço.
  • Label, do tipo string, que normalmente representa o título do pino.
  • Position, do tipo Position, que representa a latitude e longitude do pino.
  • Type, do tipo PinType, que representa o tipo de pino.

Essas propriedades são apoiadas por BindableProperty objetos, o que significa que um Pin pode ser o destino de associações de dados. Para obter mais informações sobre objetos de vinculação Pin de dados, consulte Exibir uma coleção de pinos.

Além disso, a Pin classe define MarkerClicked e InfoWindowClicked eventos. O MarkerClicked evento é disparado quando um pino é tocado e o evento é disparado InfoWindowClicked quando a janela de informações é tocada. O PinClickedEventArgs objeto que acompanha ambos os eventos tem uma única HideInfoWindow propriedade, do tipo bool.

Exibir um alfinete

Um Pin pode ser adicionado a um Map em XAML:

<ContentPage ...
             xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps">
     <maps:Map x:Name="map"
               IsShowingUser="True"
               MoveToLastRegionOnLayoutChange="False">
         <x:Arguments>
             <maps:MapSpan>
                 <x:Arguments>
                     <maps:Position>
                         <x:Arguments>
                             <x:Double>36.9628066</x:Double>
                             <x:Double>-122.0194722</x:Double>
                         </x:Arguments>
                     </maps:Position>
                     <x:Double>0.01</x:Double>
                     <x:Double>0.01</x:Double>
                 </x:Arguments>
             </maps:MapSpan>
         </x:Arguments>
         <maps:Map.Pins>
             <maps:Pin Label="Santa Cruz"
                       Address="The city with a boardwalk"
                       Type="Place">
                 <maps:Pin.Position>
                     <maps:Position>
                         <x:Arguments>
                             <x:Double>36.9628066</x:Double>
                             <x:Double>-122.0194722</x:Double>
                         </x:Arguments>
                     </maps:Position>
                 </maps:Pin.Position>
             </maps:Pin>
         </maps:Map.Pins>
     </maps:Map>
</ContentPage>

Esse XAML cria um Map objeto que mostra a região especificada pelo MapSpan objeto. O MapSpan objeto é centrado na latitude e longitude representadas por um Position objeto, que se estende 0,01 graus de latitude e longitude. Um Pin objeto é adicionado à Map.Pins coleção e desenhado Map no no local especificado por sua Position propriedade. Para obter informações sobre a Position estrutura, consulte Posição e distância do mapa. Para obter informações sobre como passar argumentos em XAML para objetos que não possuem construtores padrão, consulte Passando argumentos em XAML.

Este é o código C# equivalente:

using Xamarin.Forms.Maps;
// ...
Map map = new Map
{
  // ...
};
Pin pin = new Pin
{
  Label = "Santa Cruz",
  Address = "The city with a boardwalk",
  Type = PinType.Place,
  Position = new Position(36.9628066, -122.0194722)
};
map.Pins.Add(pin);

Aviso

A falha ao definir a Pin.Label propriedade resultará em um ArgumentException lançamento quando o Pin for adicionado a um Maparquivo .

Este código de exemplo resulta em um único pino sendo renderizado em um mapa:

Captura de tela de um pino de mapa, no iOS e Android

Interagir com um alfinete

Por padrão, quando um Pin é tocado sua janela de informações é exibida:

Captura de tela de um pino de mapa e sua janela de informações, no iOS e Android

Tocar em outro lugar no mapa fecha a janela de informações.

A Pin classe define um MarkerClicked evento, que é acionado quando um Pin é tocado. Não é necessário manipular esse evento para exibir a janela de informações. Em vez disso, esse evento deve ser manipulado quando houver um requisito para ser notificado de que um pino específico foi tocado.

A Pin classe também define um InfoWindowClicked evento que é acionado quando uma janela de informações é tocada. Esse evento deve ser tratado quando houver um requisito para ser notificado de que uma janela de informações específica foi tocada.

O código a seguir mostra um exemplo de manipulação desses eventos:

using Xamarin.Forms.Maps;
// ...
Pin boardwalkPin = new Pin
{
    Position = new Position(36.9641949, -122.0177232),
    Label = "Boardwalk",
    Address = "Santa Cruz",
    Type = PinType.Place
};
boardwalkPin.MarkerClicked += async (s, args) =>
{
    args.HideInfoWindow = true;
    string pinName = ((Pin)s).Label;
    await DisplayAlert("Pin Clicked", $"{pinName} was clicked.", "Ok");
};

Pin wharfPin = new Pin
{
    Position = new Position(36.9571571, -122.0173544),
    Label = "Wharf",
    Address = "Santa Cruz",
    Type = PinType.Place
};
wharfPin.InfoWindowClicked += async (s, args) =>
{
    string pinName = ((Pin)s).Label;
    await DisplayAlert("Info Window Clicked", $"The info window was clicked for {pinName}.", "Ok");
};

O PinClickedEventArgs objeto que acompanha ambos os eventos tem uma única HideInfoWindow propriedade, do tipo bool. Quando essa propriedade é definida como true dentro de um manipulador de eventos, a janela de informações será ocultada.

Tipos de pinos

Pin Os objetos incluem uma Type propriedade, do tipo PinType, que representa o tipo de PIN. A enumeração PinType define os seguintes membros:

  • Generic, representa um pino genérico.
  • Place, representa um alfinete para um lugar.
  • SavedPin, representa um alfinete para um local salvo.
  • SearchResult, representa um alfinete para um resultado de pesquisa.

No entanto, definir a Pin.Type propriedade como qualquer PinType membro não altera a aparência do pino renderizado. Em vez disso, você deve criar um renderizador personalizado para personalizar a aparência do pino. Para obter mais informações, consulte Personalizando um pino de mapa.

Exibir uma coleção de marcadores

A classe Map define as seguintes propriedades:

Importante

A propriedade ItemTemplate tem precedência quando as propriedades ItemTemplate e ItemTemplateSelector estão definidas.

Um Map pode ser preenchido com pinos usando a vinculação de dados para vincular sua ItemsSource propriedade a uma IEnumerable coleção:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps"
             x:Class="WorkingWithMaps.PinItemsSourcePage">
    <Grid>
        ...
        <maps:Map x:Name="map"
                  ItemsSource="{Binding Locations}">
            <maps:Map.ItemTemplate>
                <DataTemplate>
                    <maps:Pin Position="{Binding Position}"
                              Address="{Binding Address}"
                              Label="{Binding Description}" />
                </DataTemplate>
            </maps:Map.ItemTemplate>
        </maps:Map>
        ...
    </Grid>
</ContentPage>

Os ItemsSource dados da propriedade se vinculam à Locations propriedade do modelo de exibição conectado, que retorna um ObservableCollection de Location objetos, que é um tipo personalizado. Cada Location objeto define Address e Description propriedades, do tipo string, e uma Position propriedade, do tipo Position.

A aparência de cada item na IEnumerable coleção é definida definindo a ItemTemplate propriedade como um DataTemplate que contém um Pin objeto que os dados se vinculam às propriedades apropriadas.

As capturas de tela a seguir mostram uma exibição de Map uma Pin coleção usando associação de dados:

Captura de tela do mapa com pinos vinculados a dados, no iOS e Android

Escolher a aparência do item em tempo de execução

A aparência de cada item na coleção pode ser escolhida em IEnumerable tempo de execução, com base no valor do item, definindo a ItemTemplateSelector propriedade como :DataTemplateSelector

<ContentPage ...
             xmlns:local="clr-namespace:WorkingWithMaps"
             xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps">
    <ContentPage.Resources>
        <local:MapItemTemplateSelector x:Key="MapItemTemplateSelector">
            <local:MapItemTemplateSelector.DefaultTemplate>
                <DataTemplate>
                    <maps:Pin Position="{Binding Position}"
                              Address="{Binding Address}"
                              Label="{Binding Description}" />
                </DataTemplate>
            </local:MapItemTemplateSelector.DefaultTemplate>
            <local:MapItemTemplateSelector.XamarinTemplate>
                <DataTemplate>
                    <!-- Change the property values, or the properties that are bound to. -->
                    <maps:Pin Position="{Binding Position}"
                              Address="{Binding Address}"
                              Label="Xamarin!" />
                </DataTemplate>
            </local:MapItemTemplateSelector.XamarinTemplate>    
        </local:MapItemTemplateSelector>
    </ContentPage.Resources>

    <Grid>
        ...
        <maps:Map x:Name="map"
                  ItemsSource="{Binding Locations}"
                  ItemTemplateSelector="{StaticResource MapItemTemplateSelector}" />
        ...
    </Grid>
</ContentPage>

O exemplo a seguir mostra a classe MapItemTemplateSelector:

public class MapItemTemplateSelector : DataTemplateSelector
{
    public DataTemplate DefaultTemplate { get; set; }
    public DataTemplate XamarinTemplate { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        return ((Location)item).Address.Contains("San Francisco") ? XamarinTemplate : DefaultTemplate;
    }
}

A classe MapItemTemplateSelector define as propriedades DefaultTemplate e XamarinTemplate do DataTemplate como modelos de dados diferentes. O OnSelectTemplate método retorna o XamarinTemplate, que exibe "Xamarin" como um rótulo quando um Pin é tocado, quando o item tem um endereço que contém "San Francisco". Quando o item não tem um endereço que contém "São Francisco", o OnSelectTemplate método retorna o DefaultTemplate.

Observação

Um caso de uso para essa funcionalidade é vincular propriedades de objetos subclassificados Pin a propriedades diferentes, com base no Pin subtipo.

Para obter mais informações sobre seletores de modelo de dados, consulte Criando um Xamarin.Forms DataTemplateSelector.