Este artigo apresenta a aplicação - Minhas Caminhadas - com o objetivo de mostrar como criar aplicações funcionais e úteis usando o Xamarin Forms. |
Que tal criar uma aplicação que você pode usar no seu celular para algo que seja útil no seu dia a dia ?
Pensando nisso eu criei um protótipo de uma aplicação que eu chamei - Minhas Caminhadas - e que tem como objetivo gerenciar trajetos de caminhadas que você pode registrar.
Eu vou apresentar o que seria a primeira parte da aplicação onde vamos registrar as trilhas , exibir detalhes das trilhas e um mapa da trilha. Falta implementar outras funcionalidades.
Para fugir um pouco da abordagem que sempre faço ao criar aplicações Xamarin Forms, que é definir a interface via código XAML, nesta aplicação vou fazer a definição usando código C#.
Eu creio que não é uma abordagem mais adequada mas a título de exercício, nesta aplicação toda a interface vai ser definida via código C#.
O código vai estar comentado e por isso vou ser bem sucinto na descrição das rotinas.
Veja como nossa aplicação deve funcionar nesta primeira parte:
O projeto esta sendo executado em um dispositivo físico ALCATEL Pixi 4 usando o Vysor para exibir a aplicação no computador.
Então ao trabalho...
Recursos usados:
Visual Studio Community 2017 update 15.5
Criando o projeto no Visual Studio 2017 Community
Abra o Visual Studio Community 2017 e clique em New Project;
Selecione Visual C#, o template Cross-Plataform e a seguir Cross-Platform App (Xamarin.Forms);
Informe o nome XF_Analogico e clique no botão OK;
Selecione as plataformas desejadas: Android, iOS e UWP, marque o item Xamarin.Forms e a seguir escolha .NET Standard e clique no botão OK.
Nota: A partira da versão 15.5 do Visual Studio o template PCL foi substituito pelo .NET Standard.
Definindo o modelo de domínio
Vamos criar uma pasta Models no projeto e criar a classe Caminhada com o seguinte código :
public class Caminhada
{
public string Titulo { get; set; }
public string Notas { get; set; }
public double Longitude { get; set; }
public double Latitude { get; set; }
public double Kilometros { get; set; }
public string Dificuldade { get; set; }
public double Distancia { get; set; }
public string ImagemUrl { get; set; }
}
|
Esse será o modelo de domínio da nossa aplicação.
Incluindo uma referência a Xamarin.Forms.Maps no projeto
Vamos incluir no projeto via pacote Nuget uma referência a biblioteca Xamarin.Forms.Maps:
Marcando as permissões requeridas no arquivo Android Manifest
Para poder usar o recurso do Google Maps em nossa aplicação Android abra a janela de propriedades do projeto Android e marque as opções conforme abaixo:
Marque, além dessas opções, a opção Internet :
Definindo o código de inicialização da aplicação : App.cs
No código de inicialização verificamos se a plataforma for Android e chamamos a página de apresentação SplashPage ou a página principal CaminhadasPage.
using Xamarin.Forms;
namespace XFCaminhadas
{
public partial class App : Application
{
public App()
{
// verifica a plataforma
if (Device.RuntimePlatform == Device.Android)
{
MainPage = new SplashPage();
}
else
{
// a página raiz da nossa app
var navPage = new NavigationPage(new XFCaminhadas.CaminhadasPage()
{
Title = "Minhas Caminhadas"
});
MainPage = navPage;
}
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
}
|
Definindo a página de apresentação : SplashPage.cs
Todas as páginas da nossa aplicação serão somente arquivos C# com extensão .cs.
Para incluir uma página selecione o menu Project e a seguir Add New Item e clique em Content Page (C#) informando o nome da página.
Vamos iniciar criando a página SplashPage:
Abra a página SplashPage.cs e inclua o código abaixo nesta página:
using System.Threading.Tasks;
using Xamarin.Forms;
namespace XFCaminhadas
{
public class SplashPage : ContentPage
{
public SplashPage()
{
AbsoluteLayout splashLayout = new AbsoluteLayout
{
HeightRequest = 600
};
var image = new Image()
{
//define a imagem usada na tela de apresentação
Source = ImageSource.FromFile("icon.png"),
Aspect = Aspect.AspectFill,
};
//define as configurações da imagem
AbsoluteLayout.SetLayoutFlags(image, AbsoluteLayoutFlags.All);
AbsoluteLayout.SetLayoutBounds(image, new Rectangle(0f, 0f, 1f, 1f));
splashLayout.Children.Add(image);
//inclui a imagem no StackLayout
Content = new StackLayout()
{
Children = { splashLayout }
};
}
protected override async void OnAppearing()
{
base.OnAppearing();
// Tempo de espera de alguns segundos para exibir a tela inicial
await Task.Delay(4000);
// Instancia a NavigationPage com a MainPage
var navPage = new NavigationPage(new CaminhadasPage()
{
Title = "Minhas Caminhadas"
});
Application.Current.MainPage = navPage;
}
}
}
|
O código acima define a tela de apresentação com a imagem a ser exibida por 4 segundos antes de chamar a página principal : CaminhadasPage.cs
Definindo a página das trilhas : CaminhadasPage
A próxima página a ser criada é a página CaminhadasPage.cs que exibe as trilhas cadastradas em um ListView
Abra o arquivo CaminhasdasPage.cs e inclua o código abaixo:
using System.Collections.Generic;
using Xamarin.Forms;
using XFCaminhadas.Models;
namespace XFCaminhadas
{
public class CaminhadasPage : ContentPage
{
public CaminhadasPage()
{
//define a toolbar
var novaCaminhadaItem = new ToolbarItem
{
Text = "Adicionar Caminhada"
};
//define o evento Click
novaCaminhadaItem.Clicked += (sender, e) =>
{
Navigation.PushAsync(new CaminhadaInfoPage());
};
//inclui o item na toolbar
ToolbarItems.Add(novaCaminhadaItem);
//define uma trilha
var caminhadaRoteiros = new List<Caminhada>
{
new Caminhada
{
Titulo = "3 Kilometros de caminhada, Parque da Represa",
Notas = "A caminhada se inicia na entrada da represa ao lado Hospital AMA" +
" percorrendo o caminho à direita, cruzando a ponte e contornando a represa. ",
Latitude = -20.8107481,
Longitude = -49.3545277,
Kilometros = 3.1,
Distancia = 0,
Dificuldade= "Fácil",
ImagemUrl = "http://www.macoratti.net/images/represa1.jpg"
}
};
//define as propriedades do Listview e faz o binding
var itemTemplate = new DataTemplate(typeof(ImageCell));
itemTemplate.SetBinding(TextCell.TextProperty, "Titulo");
itemTemplate.SetBinding(TextCell.DetailProperty, "Notas");
itemTemplate.SetBinding(ImageCell.ImageSourceProperty,"ImagemUrl");
//define o listview para exibir as trilhas
var listaCaminhadas = new ListView
{
HasUnevenRows = true,
ItemTemplate = itemTemplate,
ItemsSource = caminhadaRoteiros,
SeparatorColor = Color.FromHex("#ddd"),
};
// Configura o tratamento de evento
listaCaminhadas.ItemTapped += (object sender,ItemTappedEventArgs e) =>
{
var item = (Caminhada)e.Item;
if (item == null) return;
Navigation.PushAsync(new CaminhadaTrilhasPage(item));
item = null;
};
Content = listaCaminhadas;
}
}
}
|
Definindo os detalhes das trilhas : CaminhadaTrilhasPage.cs
Vamos definir a exibição dos detalhes das trilhas criando a página CaminhadaTrilhasPage.cs
Abra o arquivo CaminhasdaTrilhasPage.cs e inclua o código abaixo:
using Xamarin.Forms;
using XFCaminhadas.Models;
namespace XFCaminhadas
{
public class CaminhadaTrilhasPage : ContentPage
{
public CaminhadaTrilhasPage(Caminhada caminhadaItem)
{
Title = "Trilha da Caminhada";
var inicioCaminhadaTrilha = new Button
{
BackgroundColor = Color.FromHex("#008080"),
TextColor = Color.White,
Text = "Iniciar esta trilha"
};
// define o tratamento de evento
inicioCaminhadaTrilha.Clicked += (sender, e) =>
{
if(caminhadaItem == null) return;
Navigation.PushAsync(new DistanciaPercorridaPage(caminhadaItem));
Navigation.RemovePage(this);
caminhadaItem = null;
};
var caminhadaTrilhaImagem = new Image()
{
Aspect = Aspect.AspectFill,
Source = caminhadaItem.ImagemUrl
};
var nomeTrilhaLabel = new Label()
{
FontSize = 28,
FontAttributes = FontAttributes.Bold,
TextColor = Color.Black,
Text = caminhadaItem.Titulo
};
var kilometrosTrilhaLabel = new Label()
{
FontAttributes = FontAttributes.Bold,
FontSize = 12,
TextColor = Color.Black,
Text = $"Distância : { caminhadaItem.Kilometros } km"
};
var dificuldadeTrilhaLabel = new Label()
{
FontAttributes = FontAttributes.Bold,
FontSize = 12,
TextColor = Color.Black,
Text = $"Dificuldade: { caminhadaItem.Dificuldade } "
};
var descricaoCompletaTrilha = new Label()
{
FontSize = 11,
TextColor = Color.Black,
Text = $"{ caminhadaItem.Notas }",
HorizontalOptions = LayoutOptions.FillAndExpand
};
this.Content = new ScrollView
{
Padding = 10,
Content = new StackLayout
{
Orientation = StackOrientation.Vertical,
HorizontalOptions = LayoutOptions.FillAndExpand,
Children ={
caminhadaTrilhaImagem,
nomeTrilhaLabel,
kilometrosTrilhaLabel,
dificuldadeTrilhaLabel,
descricaoCompletaTrilha,
inicioCaminhadaTrilha
}
}
};
}
}
}
|
Exibindo o mapa da trilha : DistanciaPercorridaPage.cs
Agora vamos exibir o mapa da trilha , o tempo gasto e a distância percorrida criando a página DistanciaPercorridaPage.cs
Abra o arquivo DistanciaPercorridaPage.cs criado e inclua o código abaixo:
using Xamarin.Forms;
using Xamarin.Forms.Maps;
using XFCaminhadas.Models;
namespace XFCaminhadas
{
public class DistanciaPercorridaPage : ContentPage
{
public DistanciaPercorridaPage(Caminhada caminhadaItem)
{
Title = "Distância Percorrida";
// Instanciando o nosso objeto Map
var trilhaMapa = new Map();
// Colocar uma marcação no mapa para um tipo de caminhada escolhida
trilhaMapa.Pins.Add(new Pin
{
Type = PinType.Place,
Label = caminhadaItem.Titulo,
Position = new Position(caminhadaItem.Latitude, caminhadaItem.Longitude)
});
// centraliza o mapa ao redor da lista de localização das caminhadas
trilhaMapa.MoveToRegion(MapSpan.FromCenterAndRadius(
new Position(caminhadaItem.Latitude, caminhadaItem.Longitude),Distance.FromKilometers(1.0)));
var nomeTrilhaLabel = new Label()
{
FontSize = 18,
FontAttributes = FontAttributes.Bold,
TextColor = Color.Black,
Text = caminhadaItem.Titulo
};
var distanciaCaminhadaTrilhaLabel = new Label()
{
FontAttributes = FontAttributes.Bold,
FontSize = 20,
TextColor = Color.Black,
Text = "Distância Percorrida",
HorizontalTextAlignment = TextAlignment.Center
};
var distanciaTotalPercorrida = new Label()
{
FontAttributes = FontAttributes.Bold,
FontSize = 20,
TextColor = Color.Black,
Text = $"{ caminhadaItem.Distancia } km",
HorizontalTextAlignment = TextAlignment.Center
};
var tempoTotalGastoLabel = new Label()
{
FontAttributes = FontAttributes.Bold,
FontSize = 20,
TextColor = Color.Black,
Text = "Tempo Gasto:",
HorizontalTextAlignment = TextAlignment.Center
};
var tempoTotalGasto = new Label()
{
FontAttributes = FontAttributes.Bold,
FontSize = 20,
TextColor = Color.Black,
Text = "0h 0m 0s",
HorizontalTextAlignment = TextAlignment.Center
};
var btnCaminhadas = new Button
{
BackgroundColor = Color.FromHex("#008080"),
TextColor = Color.White,
Text = "Encerrar esta trilha"
};
// trata o evento Click
btnCaminhadas.Clicked += (sender, e) =>
{
if (caminhadaItem == null) return;
Navigation.PopToRootAsync(true);
caminhadaItem = null;
};
this.Content = new ScrollView
{
Padding = 10,
Content = new StackLayout
{
Orientation = StackOrientation.Vertical,
HorizontalOptions = LayoutOptions.FillAndExpand,
Children = {
trilhaMapa,
nomeTrilhaLabel,
distanciaCaminhadaTrilhaLabel,
distanciaTotalPercorrida,
tempoTotalGastoLabel,
tempoTotalGasto,
btnCaminhadas
}
}
};
}
}
}
|
Cadastrando uma nova Trilha na página : CaminhadaInfoPage.cs
Para incluir uma nova trilha registrando suas informações vamos criar a página CaminhadaInfoPage.cs.
Abra essa página e inclua o código abaixo:
using Xamarin.Forms;
namespace XFCaminhadas
{
public class CaminhadaInfoPage : ContentPage
{
public CaminhadaInfoPage()
{
// Define o titulo da pagina
Title = "Nova Caminhada";
// Define os campos da nova caminhada
var caminhadaTitulo = new EntryCell
{
Label = "Titulo:",
Placeholder = "Titulo da Trilha"
};
var caminhadaNotas = new EntryCell
{
Label = "Notas:",
Placeholder = "Descricao"
};
var caminhadaLatitude = new EntryCell {Label = "Latitude:",Placeholder = "Latitude",Keyboard = Keyboard.Numeric};
var caminhadaLongitude = new EntryCell{Label = "Longitude:",Placeholder = "Longitude",Keyboard = Keyboard.Numeric};
var caminhadaKilometros = new EntryCell{Label = "Quilometros:",Placeholder ="Kilometros",Keyboard = Keyboard.Numeric};
var caminhadaDificuldade = new EntryCell{Label = "Nível Dificuldade:",Placeholder ="Caminhada Dificuldade"};
var caminhadaImageUrl = new EntryCell{Label = "ImageUrl:",Placeholder ="URL da Imagem"};
// Define nossa TableView
Content = new TableView
{
Intent = TableIntent.Form,Root = new TableRoot
{
new TableSection(){
caminhadaTitulo,
caminhadaNotas,
caminhadaLatitude,
caminhadaLongitude,
caminhadaKilometros,
caminhadaDificuldade,
caminhadaImageUrl
}}};
var salvarCaminhadaItem = new ToolbarItem
{
Text = "Salvar"
};
salvarCaminhadaItem.Clicked += (sender, e) =>
{
Navigation.PopToRootAsync(true);
};
ToolbarItems.Add(salvarCaminhadaItem);
}
}
}
|
E é só isso...
Vimos que podemos definir toda a interface, tratamento de eventos via Código C# sem usar código XAML.
Uma melhor prática seria definir a interface no código XAML e usar MVVM para remover todo o código da interface dos arquivos code-behind.
Como eu disse o projeto ainda não esta completo precisamos incluir funcionalidades para definir o tempo gasto na trilha , a distância percorrida e outros recursos. Fica como um exercício...
Pegue o código do projeto portable aqui : XFCaminhadas.zip (sem as referências)
"E estava ali um homem que, havia trinta
e oito anos, se achava enfermo.Jesus disse-lhe: Levanta-te, toma o teu leito, e
anda.Logo aquele homem ficou são; e tomou o seu leito, e andava. E aquele dia
era sábado."
João 5:5-9
Referências:
Xamarim - Desenvolvimento Multiplataforma com C# ... - Macoratti.net
Xamarin.Forms - Olá Mundo - Criando sua primeira ... - Macoratti.net
Xamarin.Forms - Olá Mundo - Anatomia da aplicação - Macoratti.net
https://developer.xamarin.com/api/type/Android.Widget.ListView/