Xamarin
Forms - Consumindo uma Web API ASP .NET Core e Agrupando e
Ordenando em um ListView - II
![]() |
Neste artigo vamos continuar a criação da aplicação Xamarin Forms que vai consumir uma Web API ASP .NET Core e exibir os itens em uma ListView, realizando o agrupamento e a ordenação dos itens exibidos. |
Na primeira parte do artigo apresentamos o backend; a aplicação ASP .NET Core WebAPI que expõe serviços para gerenciar informações de produtos.
Neste artigo vou mostrar o cliente, a aplicação Xamarin Forms, que vai consumir o serviço e exibir as informações dos produtos em uma ListView onde iremos realizar o agrupamento e implementar a busca e ordenação dos itens.
Então vamos à parte prática...
Recursos usados:
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);
Informe o nome XF_ConsumindoWebAPI e clique no botão OK;
A seguir selecione Blank App e marque as plataformas para quais deseja gerar os projetos;
Marque a opção Xamarin.Forms, e, em Code Sharing Strategy, marque .NET Standard, que substitui a opção de projetos PCL a partir do VS 2017 update 15.5.
![]() |
Definindo o modelo de domínio
Crie uma pasta Models no projeto portátil via menu Project -> New Folder;
Na pasta Models crie a classe Produto que representa o nosso modelo de domínio:
public class Produto
{
public int Id { get; set; }
public string Nome { get; set; }
public string Categoria { get; set; }
public decimal Preco { get; set; }
public string Foto { get; set; }
}
|
Definindo o serviço de acesso a Web API : DataService
Vamos criar uma pasta Services no projeto e nesta pasta criar a classe DataService onde vamos definir um serviço para acessar e gerenciar as informações dos produtos acessando a nossa web api.
A URI que permite acesso aos serviços definidos em nossa Web API é definido pelo local onde você publicou a Web API.
No meu exemplo a URI usada é : http://macoratti-001-site1.etempurl.com/api/produtos"
Eu estou usando o serviço de avaliação do SmarterASPNET : https://www.smarterasp.net/ , e, a uri acima tem um prazo de validade. Por isso aconselho a você a usar a sua URI, podendo mesmo ser a uri local.
Abaixo temos o código da classe DataService:
using System.Net.Http;
using XF_ConsumindoWebAPI.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Text;
namespace XF_ConsumindoWebAPI
{
public class DataService
{
HttpClient client = new HttpClient();
/// <summary>
/// Obtém os itens de produtos
/// </summary>
public async Task<List<Produto>> GetProdutosAsync()
{
var response = await client.GetStringAsync("http://macoratti-001-site1.etempurl.com/api/produtos");
var produtos = JsonConvert.DeserializeObject<List<Produto>>(response);
return produtos;
}
/// <summary>
/// Adiciona um item de produto
/// </summary>
/// <param name="itemToAdd">Item a adicionar.</param>
public async Task<int> AddProdutoAsync(Produto itemToAdd)
{
var data = JsonConvert.SerializeObject(itemToAdd);
var content = new StringContent(data, Encoding.UTF8, "application/json");
var response = await client.PostAsync("http://macoratti-001-site1.etempurl.com/api/produtos", content);
var result = JsonConvert.DeserializeObject<int>(response.Content.ReadAsStringAsync().Result);
return result;
}
/// <summary>
/// Atualiza um item
/// </summary>
/// <param name="itemIndex">indice do Item.</param>
/// <param name="itemToUpdate">Item a atualizar.</param>
public async Task<int> UpdateProdutoAsync(int itemIndex, Produto itemToUpdate)
{
var data = JsonConvert.SerializeObject(itemToUpdate);
var content = new StringContent(data, Encoding.UTF8, "application/json");
var response = await client.PutAsync(string.Concat("http://macoratti-001-site1.etempurl.com/api/produtos",
itemIndex), content);
return JsonConvert.DeserializeObject<int>(response.Content.ReadAsStringAsync().Result);
}
/// <summary>
/// Deleta um item
/// </summary>
/// <returns>O id do item a deletar.</returns>
/// <param name="itemIndex">indice do item.</param>
public async Task DeleteProdutoAsync(int itemIndex)
{
await client.DeleteAsync(string.Concat("http://macoratti-001-site1.etempurl.com/api/produtos", itemIndex));
}
}
}
|
Definindo a classe para realizar o agrupamento dos dados no ListView
Na pasta Services vamos criar uma classe chamada Agrupar que vai realizar o agrupamento dos produtos pelas categorias em nossa aplicação conforme mostra o código a seguir:
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace XF_ConsumindoWebAPI.Services
{
public class Agrupar<TKey, TItem> : ObservableCollection<TItem>
{
public TKey Key { get; private set; }
public Agrupar(TKey key, IEnumerable<TItem> items)
{
this.Key = key;
foreach (var item in items)
this.Items.Add(item);
}
}
}
|
No código acima o parâmetro Tkey representa o item pelo qual iremos agrupar as informações e TItem representa as informações dos produtos que serão agrupadas.
Essa classe herda de ObservableCollection permitindo assim, adicionar ou remover itens de um grupo existente, ela também define o critério para realizar o agrupamento.
Definindo o código da página MainPage
Abra o arquivo MainPage.xaml e inclua o código 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_ConsumindoWebAPI"
x:Class="XF_ConsumindoWebAPI.MainPage"
BackgroundColor="White">
<StackLayout Orientation="Vertical">
<Label Text="Lista de Produtos" TextColor="Red" />
<SearchBar x:Name="sbProcurar" Placeholder="Procurar..." TextChanged="Procurar_TextChanged"/>
<ListView x:Name="produtoLista" Margin="5"
HasUnevenRows="True"
IsGroupingEnabled="True"
GroupDisplayBinding="{Binding Key}"
SeparatorVisibility="Default"
SeparatorColor="Black">
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell Text="{Binding Nome}"
Detail="{Binding Preco, StringFormat='R{0:c}'}"
ImageSource="{Binding Foto}"
TextColor="Black" DetailColor="Blue"/>
/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
|
Para poder agrupar as informações da nossa agenda primeiro vamos temos que habilitar o nosso ListView a aceitar o agrupamento definindo as seguintes propriedades:
Para exibir os produtos usamos um ItemTemplate e a célula ImageCell :
Text - para exibir a primeira linha de texto em fonte maior;
Detail - para exibir uma segunda linha de texto em fonte menor;
ImageSource - para exibir uma imagem próxima ao texto
Definimos também uma SearchBar que vai permitir procurar os produtos por categoria. Para isso vamos usar o evento TextChanged e definir o código para filtrar pelo nome da categoria.
Vamos agora implementar o código no arquivo MainPage.xaml.cs :
Abra o arquivo MainPage.xaml.cs criado no projeto e a seguir defina o código abaixo:
using System;
using System.Collections.Generic;
using System.Linq;
using Xamarin.Forms;
using XF_ConsumindoWebAPI.Models;
using XF_ConsumindoWebAPI.Services;
namespace XF_ConsumindoWebAPI
{
public partial class MainPage : ContentPage
{
DataService dataService;
List<Produto> items;
public MainPage()
{
InitializeComponent();
dataService = new DataService();
AtualizaDados();
}
private async void AtualizaDados()
{
items = await dataService.GetProdutosAsync();
produtoLista.ItemsSource = Listar();
}
private void Procurar_TextChanged(object sender, TextChangedEventArgs e)
{
produtoLista.ItemsSource = this.Listar(this.sbProcurar.Text);
}
public IEnumerable<Agrupar<string, Produto>> Listar(string filtro = "")
{
IEnumerable<Produto> produtosFiltrados = this.items;
if (!string.IsNullOrEmpty(filtro))
produtosFiltrados = items.Where(l => (l.Nome.ToLower().Contains(filtro.ToLower()))
|| l.Categoria.ToLower().Contains(filtro.ToLower()));
return from produto in produtosFiltrados
orderby produto.Nome
group produto by produto.Categoria into grupos
select new Agrupar<string, Produto>(grupos.Key, grupos);
}
}
}
|
No código estamos criando uma instância da classe DataService e chamando o método AtualizaDados que obtêm as informações de todos os produtos: dataService.GetProdutosAsync(); e chamando o método Listar() realizar o agrupamento e atribui o resultado à propriedade ItemsSource da listview produtoLista.
Executando o projeto iremos obter o seguinte resultado :
![]() |
![]() |
Vemos agora as informações da agenda agrupadas em ordem alfabética pela categoria.
Podemos ainda procurar por uma categoria usando a SearchBar.
Pegue o
código usado no projeto aqui :
XF_ConsumindoWebAPI.zip (somente o projeto compartilhado)
"Levantai os vossos olhos para os céus,
e olhai para a terra em baixo, porque os céus desaparecerão como a fumaça, e a
terra se envelhecerá como roupa, e os seus moradores morrerão semelhantemente;
porém a minha salvação durará para sempre, e a minha justiça não será abolida."
Isaías 51:6
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a
Objetos com VB .NET
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
Xamarin Forms - Criando uma página de pequisa - Macoratti.net
Xamarin.Forms - Acessando a base de filmes do ... - Macoratti.net