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:
Quando um Pin
objeto é adicionado à Map.Pins
coleção, o pino é renderizado no mapa.
A classe Pin
tem as propriedades a seguir:
Address
, do tipostring
, que normalmente representa o endereço do local do pino. No entanto, pode ser qualquerstring
conteúdo, não apenas um endereço.Label
, do tipostring
, que normalmente representa o título do pino.Position
, do tipoPosition
, que representa a latitude e longitude do pino.Type
, do tipoPinType
, 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 Map
arquivo .
Este código de exemplo resulta em um único pino sendo renderizado em um mapa:
Interagir com um alfinete
Por padrão, quando um Pin
é tocado sua janela de informações é exibida:
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:
ItemsSource
, do tipoIEnumerable
, que especifica a coleção deIEnumerable
itens a serem exibidos.ItemTemplate
, do tipoDataTemplate
, que especifica oDataTemplate
a ser aplicado a cada item na coleção de itens exibidos.ItemTemplateSelector
, do tipoDataTemplateSelector
, que especifica oDataTemplateSelector
que será usado para escolher umDataTemplate
para um item em tempo de execução.
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:
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.