Xamarin Forms - Clonando o Google List - CardView

 Neste artigo eu vou mostrar como podemos 'clonar' a exibição do Google List simulando um CardView em uma aplicação Xamarin Forms.

O widget Cardview é um componente de interface de usuário que apresenta conteúdo de texto e imagem em modos de exibição que se assemelham a cartões.

Este widget Cardview foi introduzido no Android 5.0 (Lollipop), e é um componente de UI que apresenta conteúdo de texto e imagem em modos de exibição que se assemelham a cartões.  O CardView é implementado como um widget FrameLayout com cantos arredondados e uma sombra.

A figura abaixo mostra a utilização deste widget no Google List que esta sendo executado no meu celular e exibido via Vysor no computador:

Então neste artigo eu vou mostrar como 'clonar' a visualização do CardView em uma aplicação Xamarin Forms.

Para isso vamos traçar o roteiro das tarefas que vamos realizar:

Recursos Usados

Criando o projeto Xamarin Forms

Abra o  VS 2017 Community update 15.5 e clique em New Project e a seguir escolha Cross Platform -> Cross Platform App (Xamarin.Forms) e informe o nome XF_CardView1;

Ao criar um projeto Xamarin Forms em uma versão anterior à atualização 15.5, você tinha duas opções para compartilhar o código entre as plataformas:

  1. Shared Project

  2. Portable Class Library (PCL)

Pois a partir da versão 15.5 do Visual Studio(lançada em dezembro/2017) a opção Portable Class Library (PCL) foi substituida pela .NET Standard:

Marque as opções Android e/ou iOS, marque Xamarin Forms e a seguir marque .NET Standard e clique no botão OK.

Pronto nosso projeto já esta criado.

Vamos criar 3 novas pastas este projeto usando o menu Project -> New Folder :

A seguir selecione algumas imagens e as copie para a pasta Resources/drawable do projeto Android. Eu vou usar imagens nomeadas como: Imagem_1.jpg, Image_2.jpg, etc.

Se você for executar a aplicação no iOS deverá copiar a imagem também para a pasta Resources.

Vamos exibir imagens arredondadas e para isso vamos usar o plugin Xam.Plugins.Forms.CircleImage. Vamos incluir este pacote no projeto via Nuget.

No menu Tools acione a opção Manage Nuget Packages for Solution. Clique na guia Browse e localize e instale o pacote:

Criando o modelo de domínio:  CardViewModel

Na pasta Models crie a classe CardViewModel que define o modelo de domínio e que será usado para exibir o cabeçalho, as linhas de texto, a descrição e as imagens no ListView.

    public class CardViewModel
    {
        public string Cabecalho { get; set; }
        public string Linhas { get; set; }
        public string Descricao { get; set; }
        public string Imagem { get; set; }
    }

Criando o template para o CardView usando ContentView

Na pasta Views crie uma ContentView onde será definido o leiaute da view que iremos usar para simular o CardView.

Uma ContentView nos fornece um container de um único elemento que contém um único elemento filho.

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XF_CardView.Views.CardViewTemplate"
             xmlns:controls="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=
ImageCircle.Forms.Plugin.Abstractions"
             xmlns:local="clr-namespace:XF_CardView">
    <Frame IsClippedToBounds="True" HasShadow="True" BackgroundColor="White" >
        <Frame.OutlineColor> 
            <OnPlatform x:TypeArguments="Color" Android="Gray" iOS="Gray"/>
        </Frame.OutlineColor>
        <Frame.Margin>
            <OnPlatform x:TypeArguments="Thickness" Android="7" iOS="7"/>
        </Frame.Margin>
        <Frame.Padding>
            <OnPlatform x:TypeArguments="Thickness" Android="5" iOS="5"/>
        </Frame.Padding>
        <StackLayout Orientation="Horizontal">
            <Grid VerticalOptions="CenterAndExpand" Padding="0"
                  HorizontalOptions="FillAndExpand" BackgroundColor="Transparent">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                <StackLayout Orientation="Horizontal" VerticalOptions="Start" >
                    <controls:CircleImage Source="{Binding Imagem}" VerticalOptions="Start" HeightRequest="30" 
WidthRequest="30"></controls:CircleImage>
                    <Label FontAttributes="None" Grid.Row="0"
                       HorizontalTextAlignment="Start"
                       VerticalTextAlignment="Center"
                       FontSize="12"
                       Text="{Binding Cabecalho , Mode = TwoWay}" TextColor="Gray" >
                    </Label>
                </StackLayout>                
                <Grid Grid.Row="1">
                    <StackLayout Orientation="Horizontal">
                        <Label FontAttributes="None" Grid.Row="1"
                           HorizontalTextAlignment="Start"
                           VerticalTextAlignment="Start"
                           FontSize="12" Text="{Binding Linhas, Mode = TwoWay}" 
                               TextColor="Black">
                        </Label>
                        <Image Source="{Binding  Imagem}"  Grid.Row="2"  WidthRequest="50" 
                               HeightRequest="50" HorizontalOptions="End" />
                    </StackLayout>
                </Grid>                
                <Grid Grid.Row="2" BackgroundColor="Transparent" Padding="4">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Label Grid.Row="0" Grid.Column="0" />
                    <Label Grid.Row="0" Grid.Column="0"
                        Text="{Binding Descricao}" HorizontalOptions="Start" VerticalOptions="Start"/>
                </Grid>                
            </Grid>
        </StackLayout>
    </Frame>
</ContentView>

Neste código estamos usando as views Frame, Grid, StackLayout , Label, etc. para definir um leiaute para exibir as informações do CardView.

Perceba que estamos realizando o Binding com as propriedades definida em nosso modelo de domínio.

Para poder usar o puglin para exibir imagens circulares definimos o namespace na definição da ContentView:

 xmlns:controls="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin.Abstractions"

Criando a view model : CardViewModelViewModel

Na pasta ViewModels crie uma classe chamada CardViewModelViewModel e defina o código que vai criar uma lista contendo as informações que iremos exibir:

using System.Collections.Generic;
using System.Collections.ObjectModel;
using XF_CardView.Model;
namespace XF_CardView.ViewModels
{
    public class CardViewModelViewModel
    {
        public IList<CardViewModel> CardViewCollection { get; set; }
        public object SelectedItem { get; set; }
        public CardViewModelViewModel()
        {
            CardViewCollection = new List<CardViewModel>();
            GerarCardViewModel();
        }
        private void GerarCardViewModel()
        {
            CardViewCollection = new ObservableCollection<CardViewModel>
            {
                    new CardViewModel
                    {
                         Cabecalho = " 1 dia atrás   - FaceBook ",
                         Linhas= "Facebook com Android 7.0 certificado - GSM Arena News " ,
                         Imagem = "Imagem_4.jpg",
                         Descricao = "Facebook é uma rede social lançada em 4 de fevereiro...........exemplo de texto 
usado para testar a clonagem do cardview no Xamarin Forms em 2018",
                    },
                    new CardViewModel
                    {
                         Cabecalho = " 9 hrs atrás   - The Indipendendent",
                         Linhas="Game of THrones season 7 : Fans think Catelyn's Stark's Ghost was" ,
                         Descricao = "O Independente é um jornal on-line britânico.[2]...........exemplo de texto usado 
para testar a clonagem do cardview no Xamarin Forms em 2018",
                         Imagem = "Imagem_2.jpg"
                    },
                    new CardViewModel
                    {
                        Cabecalho = " 10 hrs atrás  - Power BI Microsoft",
                        Linhas    = "Anunciando a solução Power BI Solution para conectividade Azure Log" ,
                        Descricao = "Microsoft Corporation (/ˈmaɪkrəˌsɒft/,[2][3] abreviada...........exemplo de texto 
usado para testar a clonagem do cardview no Xamarin Forms em 2018",
                        Imagem    = "Imagem_3.jpg"
                    },
                    new CardViewModel
                    {
                        Cabecalho = " 13 hrs atrás  - SQL Server Management Studio ",
                        Linhas    = "SQL Server é um banco de dados relacional ou SGBD que permite a criação de 
banco de dados e tabelas em suas aplicações",
                        Descricao = "Google Maps usado para localizar endereços e sua localização",
                        Imagem    = "Imagem_7.jpg"
                    },
                    new CardViewModel
                    {
                        Cabecalho = " 15 hrs atrás - Android Autoridadae",
                        Descricao = "Se você já leu o livro de Julio Verne...........exemplo de texto usado para testar a 
clonagem do cardview no Xamarin Forms." ,
                        Linhas    = "Definições e escolhas feitas a esmo : 5 coisas que você deve saber sobre o seu celular" ,
                        Imagem    = "Imagem_5.jpg"
                    },
                };
        }
    }
}

Definindo o código na página MainPage

Abra o arquivo MainPage.xaml e inclua no 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:view="clr-namespace:XF_CardView.Views;assembly=XF_CardView"
             xmlns:viewModel="clr-namespace:XF_CardView.ViewModels;assembly=XF_CardView"
             xmlns:local="clr-namespace:XF_CardView"
             x:Class="XF_CardView.MainPage">
    <ContentPage.BindingContext>
        <viewModel:CardViewModelViewModel/>
    </ContentPage.BindingContext>
    <StackLayout Orientation="Vertical">
        <Label Text="Google List View"
             VerticalOptions="Start"
             HorizontalTextAlignment="Center"
             VerticalTextAlignment="Center"
             BackgroundColor="Transparent"
             HorizontalOptions="CenterAndExpand" />
        <ListView x:Name="listView" SelectedItem="{Binding SelectedItem , Mode=TwoWay }" 
              RowHeight="150" 
              ItemsSource="{Binding CardViewCollection}" HasUnevenRows="True"  >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <view:CardViewTemplate/>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

Neste código temos:

Um controle StackLayout que esta empilhando os controles :

1- Label onde definimos o título 'Google List View'

2- 1 ListView onde estamos usando o ItemsSource para definir a fonte de dados que será oriunda da coleção CardViewCollection;

3- 1 DataTemplate onde vamos definir uma ViewCell e utilizar o template CardViewTemplate para exibir os dados;

Podemos usar um DataTemplate para definir modelo de exibição de dados que podem ser criados inline, em um ResourceDictionary, ou de um tipo personalizado ou tipo de célula Xamarin.Forms apropriado.

Um cenário de uso comum para um DataTemplate é exibir dados de uma coleção de objetos em um ListView. A aparência dos dados para cada célula no ListView pode ser gerenciada configurando a propriedade ListView.ItemTemplate para um DataTemplate.

Observe que estamos realizando o BindingContext via XAML.

Outra opção seria fazer isso via código : BindingContext = new CardViewModelViewModel();

Executando o projeto usando o emulador Genymotion para o Android iremos obter o seguinte resultado:



Pegue o código do projeto compartilhado aqui :   XF_CardView.zip (sem as referências)

'E o testemunho é este: que Deus nos deu a vida eterna; e esta vida está em seu Filho.(Jesus Cristo)'
1 João 5:11
 

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 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti