Neste artigo, mostrarei como podemos usar o header e footer do ListView para exibir informações e totalizações em aplicações Xamarin Forms, usando o Visual Studio 2017 e a linguagem C#.
A view ListView é uma das mais importantes views do Xamarin Forms e apresenta uma versatilidade fantástica que podemos aproveitar em nossas aplicações.
Vou criar uma agenda de contatos e exibir uma relação de contatos com nome e e-mail em um ListView, aproveitando para mostrar como exibir informações no Header e como exibir o total de contatos no Footer.
Recursos usados:
- Visual Studio Community 2017 ou Xamarin Studio
- Xamarin
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 Plataform App(Xamarin.Forms or Native)
- Informe o nome XF_AgendaContatos e clique no botão OK
- A seguir selecione Blank App e marque as opções – Xamarin.Forms e Portable Class Library (PCL) e clique em OK
Será criado um projeto contendo no projeto Portable as páginas App.xaml e MainPage.xaml.
No code-behind do arquivo App.xaml, temos a classe App.cs que irá conter o código compartilhado e que vamos usar neste artigo.
No arquivo App.cs, inclua o código a seguir onde definimos a página principal da aplicação como sendo a página MainPage:
using Xamarin.Forms; namespace XF_RealmDB { public partial class App : Application { public App() { InitializeComponent(); MainPage = new NavigationPage(new XF_PclStorage.MainPage()); } 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 } } }
Ao final, teremos as referências incluídas em todos os projetos da nossa solução. Iremos usar a página MainPage.xaml como página principal da nossa aplicação.
Definindo o Model e o Serviço
Vamos agora definir o nosso modelo de domínio e o serviço que preenche o modelo com algumas informações sobre contatos.
Criaremos uma pasta Model no projeto e o arquivo Contato.cs, definindo a classe Contato com o seguinte código:
public class Contato { public string Nome { get; set; } public string Email { get; set; } }
A seguir, crie o arquivo ContatoService.cs e defina a classe ContatoService conforme o código mostrado a seguir:
using System.Collections.ObjectModel; namespace XF_AgendaContatos.Model { public class ContatoService { /// <summary> /// Obtém a lista com todos os contatos registrados. /// </summary> public ObservableCollection<Contato> TodosContatos { get; private set; } /// <summary> /// Inicializa uma instância dessa classe populando a lista de contatos. /// </summary> public ContatoService() { TodosContatos = new ObservableCollection<Contato> { new Contato { Nome = "Jose Macoratti", Email = "egestas@anequeNullam.co.uk" }, new Contato { Nome = "Maria Julia", Email = "a.tortor@Sed.net" }, new Contato { Nome = "Osmar Bueno", Email = "tristique@faucibusutnulla.net" }, new Contato { Nome = "Yuri Lima", Email = "montes.nascetur.ridiculus@fringillaest.ca" }, new Contato { Nome = "Leonardo Silveira", Email = "imperdiet.ullamcorper@Quisque.com" }, new Contato { Nome = "Nadir Figueiredo", Email = "adipiscing@anteipsum.ca" }, new Contato { Nome = "Emely Soares", Email = "aliquet.molestie.tellus@Nam.net" }, }; } } }
Esta classe define uma lista de contatos que será a nossa fonte de dados usada no projeto. Note que estamos usando a coleção ObservableCollection() que implementa a interface INotifyPropertyChanged.
Definindo a ViewModel
Crie uma pasta ViewModel no projeto, e a seguir crie o arquivo ContatoListViewModel.cs nesta pasta, definindo o código abaixo na ViewModel ContatoListViewModel:
using System.Collections.Generic; using System.Linq; using XF_AgendaContatos.Model; namespace XF_AgendaContatos.ViewModel { public class ContatoListViewModel { //define a fonte do listview e a quantidade de itens a ser exibida no rodape public IList<Contato> Items { get; private set; } public int ItemsCount { get; private set; } //define o telefone a ser exibido na view (não existe no model) public string Telefone { get; private set; } = "+55 (11) 9807-0055"; //construtor public ContatoListViewModel() { var repo = new ContatoService(); Items = repo.TodosContatos.OrderBy(c => c.Nome).ToList(); ItemsCount = repo.TodosContatos.Count; } } }
Na ViewModel definimos a propriedade Items que representa a nossa lista de contatos, a propriedade ItemsCount que representa o total de itens da lista e a propriedade Telefone.
Observe que as propriedades ItemsCount e Telefone não existem no Model, elas foram definidas apenas na ViewModel para serem exibidas no rodapé e no cabeçalho.
Definindo a View: MainPage
Vamos agora definir o código da view MainPage.xaml conforme abaixo:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:XF_AgendaContatos" BackgroundColor="Aquamarine" x:Class="XF_AgendaContatos.MainPage" Title="Agenda Contatos"> <ListView x:Name="ContatosListView" ItemsSource="{Binding Items}" Header="{Binding}" Footer="{Binding}"> <ListView.ItemTemplate> <DataTemplate> <TextCell Text="{Binding Nome}" Detail="{Binding Email, StringFormat='E-mail: {0}'}" DetailColor="Blue"/> </DataTemplate> </ListView.ItemTemplate> <ListView.HeaderTemplate> <DataTemplate> <ContentView BackgroundColor="Beige"> <Label Margin="16" HorizontalOptions="CenterAndExpand" Text="{Binding Telefone, StringFormat='Meu Fone: {0}'}" /> </ContentView> </DataTemplate> </ListView.HeaderTemplate> <ListView.FooterTemplate> <DataTemplate> <ContentView BackgroundColor="Beige"> <Label Margin="16" HorizontalOptions="CenterAndExpand" Text="{Binding ItemsCount, StringFormat='Total de Contatos: {0}'}" /> </ContentView> </DataTemplate> </ListView.FooterTemplate> </ListView> </ContentPage>
No código, definimos o ListView e sua propriedade ItemsSource usando o databinding para a lista de contatos Items.
Definimos também o Header e Footer usando a notação {Binding} sem definir um Source ou Path. Fazendo assim, o XAML entende que o objeto que será usado para o Binding será o mesmo do BindingContext atual. Como o ListView propaga esse objeto para os templates Header e Footer isso não é necessário.
A seguir, definimos o HeaderTemplate e FooterTemplate configurados para exibir as propriedades Telefone e ItemsCount.
Abra o arquivo MainPage.xaml.cs criado no projeto e a seguir defina o código abaixo:
using Xamarin.Forms; using XF_AgendaContatos.ViewModel; namespace XF_AgendaContatos { public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); BindingContext = new ContatoListViewModel(); } } }
No código, estamos criando uma instância da nossa ViewModel e atribuindo ao BindingContext.
Executando o projeto iremos obter o seguinte resultado (nosso projeto padrão é o projeto Android):
Conforme esperado, estamos exibindo o telefone no Header e o total de contatos no Footer.
Pegue o código do projeto aqui: XF_AgendaContatos.zip (sem as referências).