quinta-feira, 23 de maio de 2019

Android – Trabalhando com o RecyclerView



Caro leitor, este mês continuarei trabalhando com dicas para desenvolver com a ferramenta Android Studio. Utilizaremos o widget “RecyclerView” em conjunto com o “CardView”. Para quem não conhece este último, recomendo a leitura do artigo “Conhecendo e Utilizando o CardView” do mês de Janeiro de 2017.

O “RecyclerView” tem a função de exibir uma listagem de dados para o usuário, assim como o antigo “ListView”, o qual também possui esta funcionalidade. De acordo com sua documentação oficial, temos algumas vantagens deste widget, tais como:

- Animações padrões para operações de itens comuns, para remoção ou adição de itens;
- Modularização, ou seja, podemos inserir comportamentos no mesmo intercambiando componentes internos da View;
- É mais performático, ou seja, implementa a classe ”ViewHolder” impedindo algumas chamadas do método “findViewById” desnecessariamente. Teremos um nível de abstração maior entre a lista de dados do usuário e a ‘View”, deixando assim o componente mais performático.

Na Figura 01 podemos conferir a estrutura hierárquica.



Figura 01: Estrutura Hierárquica.

Para entendermos melhor, montaremos um exemplo prático criando uma classe de Produtos com alguns atributos, tais como: Id, Nome e Valor, um arquivo de layout contendo a estrutura completa destes atributos seguido de um “CardView” para organização e a classe “Adapter” do “RecyclerView”, o qual fará toda a tarefa interna da classe “Produtos”.


Importando a Biblioteca
Recomendo criar um projeto do início defindo um nome para o mesmo, no nosso caso defini como “appRecyclerView”. Teremos a estrutura padrão, contendo a classe “MainActivity” e o layout “activity_main”. No arquivo de configuração “build.gradle” iremos inserir as dependências do “RecyclerView” juntamente com a “CardView”. (No artigo do mês passado abordo esta técnica com maiores detalhes). O trecho da codificação ficará da seguinte maneira:
dependencies
{
    . . .

   
compile 'com.android.support:appcompat-v7:24.1.1'
   
compile 'com.android.support:cardview-v7:24.1.1'
   
compile 'com.android.support:recyclerview-v7:24.1.1'
    . . .
}

Criando um exemplo prático
Antes de partirmos para codificação da classe principal “MainActivity”, criaremos alguns pré-requisitos como a: Classe “Produtos” (onde o usuário irá inserir os dados) e o layout “componente_produtos” (será responsável pela organização na tela do dispositivo).
Classe Produtos
Para criar uma classe clique com o botão direito sobre o pacote do projeto escolhendo “New/Java Class”. Defina como “Produtos”, teremos uma codificação idêntica da listagem 01.
package exemplo.apprecyclerview;

public class Produtos
{
  
private int Id;
  
private String Nome;
  
private double Valor;

  
public int getId()
   {
    
return Id;
   }

  
public void setId(int id)
   {
     
Id = id;
   }
  
  
public String getNome()
   {
     
return Nome;
   }
  
  
public void setNome(String nome)
   {
     
Nome = nome;
   }
  
  
public double getValor()
   {
     
return Valor;
   }
  
  
public void setValor(double valor)
   {
     
Valor = valor;
   }
   public Produtos()
   {
     
super();
   }
}
Listagem 01.

Layout “componente_produtos”
Para criar itens do tipo Layout localize o caminho “res/layout” escolhendo “New/Layout Resource File”. Defina o nome para “componente_produtos”. Confira o layout na Figura 02 e codificação na Listagem 02.


Figura 02: Layout do componente.

 
O XML correspondente:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   
android:layout_width="match_parent"
   
android:layout_height="wrap_content"
   
android:orientation="vertical">

    <
android.support.v7.widget.CardView
       
android:id="@+id/card_view"
       
android:foreground="?android:attr/selectableItemBackground"
       
android:layout_gravity="center"
       
android:clickable="true"
       
android:layout_width="match_parent"
       
android:layout_height="match_parent">

        <
LinearLayout
           
android:layout_width="wrap_content"
           
android:layout_height="wrap_content"
           
android:orientation="horizontal"
           
android:padding="5dp">
            <
LinearLayout
               
android:layout_width="wrap_content"
               
android:layout_height="wrap_content"
               
android:orientation="vertical">
                <
LinearLayout
                   
android:layout_width="wrap_content"
                   
android:layout_height="wrap_content"
                   
android:orientation="horizontal">
                    <
TextView android:id="@+id/complblId1"
                       
android:layout_width="wrap_content"
                       
android:layout_height="wrap_content"
                       
android:text="Id: "
                       
android:textStyle="bold"
                       
android:textAppearance="?android:attr/textAppearanceSmall" />
                    <
TextView android:id="@+id/comptxtId1"
                       
android:layout_width="wrap_content"
                       
android:layout_height="wrap_content"
                       
android:textAppearance="?android:attr/textAppearanceSmall" />
                </
LinearLayout>

                <
LinearLayout
                   
android:layout_width="wrap_content"
                   
android:layout_height="wrap_content"
                   
android:orientation="horizontal">
                    <
TextView android:id="@+id/complbNome2"
                       
android:layout_width="wrap_content"
                       
android:layout_height="wrap_content"
                       
android:text="Nome: "
                       
android:textStyle="bold"
                       
android:textAppearance="?android:attr/textAppearanceSmall" />
                    <
TextView android:id="@+id/comptxtNome2"
                       
android:layout_width="wrap_content"
                       
android:layout_height="wrap_content"
                       
android:textAppearance="?android:attr/textAppearanceSmall" />
                </
LinearLayout>

                <
LinearLayout
                   
android:layout_width="wrap_content"
                   
android:layout_height="wrap_content"
                   
android:orientation="horizontal">
                    <
TextView android:id="@+id/complbValor3"
                       
android:layout_width="wrap_content"
                        
android:layout_height="wrap_content"
                       
android:text="Valor: "
                       
android:textStyle="bold"
                       
android:textAppearance="?android:attr/textAppearanceSmall" />
                    <
TextView android:id="@+id/comptxtValor3"
                       
android:layout_width="wrap_content"
                       
android:layout_height="wrap_content"
                       
android:textAppearance="?android:attr/textAppearanceSmall" />
                </
LinearLayout>
            </
LinearLayout>
        </
LinearLayout>
    </
android.support.v7.widget.CardView>
</
LinearLayout>
Listagem 02.
Adicionamos um “CardView” e dentro do mesmo distribuímos os “Layouts” responsáveis por organizar os TextViews (Id, Nome e Valor). 
Codificação na Classe “MainActivity”
Toda classe principal também possuirá um retorno em um arquivo de layout. Primeiramente iremos inserir o widget “RecyclerView” neste layout. Veja Imagem 03.


Figura 03: Layout “activity_main”.
 
O XML Correspondente:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
   
xmlns:android="http://schemas.android.com/apk/res/android"
   
xmlns:tools="http://schemas.android.com/tools"
   
android:id="@+id/activity_main"
   
android:layout_width="match_parent"
   
android:layout_height="match_parent"
   
android:paddingLeft="@dimen/activity_horizontal_margin"
   
android:paddingRight="@dimen/activity_horizontal_margin"
   
android:paddingTop="@dimen/activity_vertical_margin"
   
android:paddingBottom="@dimen/activity_vertical_margin"
   
tools:context="exemplo.apprecyclerview.MainActivity">

    <
android.support.v7.widget.RecyclerView
       
android:id="@+id/rvProdutos"
       
android:layout_width="match_parent"
       
android:layout_height="match_parent"/>
</
RelativeLayout>
Listagem 03.

Na “MainActivity” Teremos a codificação abaixo comentada nas principais regiões.

package exemplo.apprecyclerview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;

Deveremos importar algumas bibliotecas, tais como a “LinearLayoutManager” responsável pela configuração do Layout, o “RecyclerView” para trabalhar com este componente, entre outras.

public class MainActivity extends AppCompatActivity {

   
private List<Produtos> lstProdutos = new ArrayList<>();
   
private RecyclerView rvProdutos;
   
private ProdutosAdapter adpProdutos;
   
private RecyclerView.LayoutManager layoutProdutos;

Usaremos algumas variáveis privadas, sendo a “lstProdutos” para englobar a classe Produtos através de um “ArrayList”, a “rvProdutos” para realizar a referência ao “RecyclerView”, a “adpProdutos” para armazenar os dados da classe Produtos e por último a “layoutProdutos”, a qual qual irá organizar os dados de uma forma mais eficaz.

   
@Override
   
protected void onCreate(Bundle savedInstanceState)
    {
       
super.onCreate(savedInstanceState);
        setContentView(R.layout.
activity_main);

       
rvProdutos = (RecyclerView) findViewById(R.id.rvProdutos);

        List<Produtos> listaprodutos =
new ArrayList<Produtos>();
        Produtos produtos =
new Produtos();
        produtos.setId(
1);
        produtos.setNome(
"Abacaxi");
        produtos.setValor(
1.99);
        listaprodutos.add(produtos);

        Produtos produtos2 =
new Produtos();
        produtos2.setId(
2);
        produtos2.setNome(
"Laranja");
        produtos2.setValor(
3.59);
        listaprodutos.add(produtos2);

        Produtos produtos3 =
new Produtos();
        produtos3.setId(
3);
        produtos3.setNome(
"Melão");
        produtos3.setValor(
4.99);
        listaprodutos.add(produtos3);

       
lstProdutos = listaprodutos;
       
layoutProdutos = new LinearLayoutManager(this);
       
adpProdutos = new ProdutosAdapter(lstProdutos);
       
rvProdutos.setAdapter(adpProdutos);
       
rvProdutos.setLayoutManager(layoutProdutos);
       
adpProdutos.notifyDataSetChanged();
    }

No método “OnCreate”, após a chamada do método “setContentView(R.layout.activity_main)”, iniciaremos o componente “RecyclerView” pelo método “FindViewById”. Instanciaremos a classe “Produtos” para inserir alguns dados aleatórios para setar na variável “lstProdutos” logo em seguida. Definiremos um “Layout” com o auxílio do “LinearLayoutManager”. O adapter “adpProdutos” será alimentado pelo método da classe “ProdutorAdapter”, a qual será implementada logo abaixo. Setaremos também o adapter e layout em nosso rvProdutos (RecyclerView).

public class ProdutosAdapter extends RecyclerView.Adapter<ProdutosAdapter.MyViewHolder> {

       
private List<Produtos> ListaProdutos;

Teremos que criar a variável “List<Produtos>” para trabalharmos com o Adapter “ProdutosAdapter”. Extenderemos a classe “RecyclerView.Adapter”, portanto seremos forçados a utilizar alguns métodos, os quais veremos logo adiante.

       
public class MeuViewHolder extends RecyclerView.ViewHolder
        {
           
public TextView Id, Nome, Valor;

            public MeuViewHolder(View view) {
               
super(view);
               
Id = (TextView) view.findViewById(R.id.comptxtId1);
               
Nome = (TextView) view.findViewById(R.id.comptxtNome2);
               
Valor = (TextView) view.findViewById(R.id.comptxtValor3);
            }
        }

A classe “MeuViewHolder” irá servir como suporte para definirmos a View, e os TextViews, sendo o Id, Nome e Valor.

       
public ProdutosAdapter(List<Produtos> Produtos)
        {
           
this.ListaProdutos = Produtos;
        }

O método acima irá armazenar os produtos.

       
@Override
       
public MeuViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
        {
            View itemView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.
componente_produtos, parent, false);

           
return new MeuViewHolder(itemView);
        }

Já o método sobrescrito “MeuViewHolder” irá criar nossa view usando o “LayoutInflater” com o parâmetro contexto inflando o layout “componente_produtos” criado anteriormente.

       
@Override
       
public void onBindViewHolder(MeuViewHolder holder, int position)
        {
            Produtos item =
ListaProdutos.get(position);
            holder.
Id.setText(String.valueOf(item.getId()));
            holder.
Nome.setText(item.getNome());
            holder.
Valor.setText(String.valueOf(item.getValor()));
        }

       
@Override
       
public int getItemCount()
        {
           
return ListaProdutos.size();
        }
    }

No “onBindViewHolder”, pela posição do item, iremos alimentar o “MeuViewHolder”, o qual irá mostrar o resultado na tela do dispositivo móvel. Com nosso aplicativo rodando, teremos um resultado idêntico ao da Figura 04.

}

Figura 04: Exemplo funcionando.


Conclusões
Neste artigo procurei descrever através da criação de um exemplo, o funcionamento deste importante widget. Foi criada uma classe específica sobrescrevendo alguns métodos necessários para realização desta tarefa. Aproveitei e implantei funcionalidades básicas para obter um resultado melhor.
Fica aí a dica, um abraço e até o mês que vem!
Referências

Sobre o autor
Thiago Cavalheiro Montebugnoli adora aprender novas tecnologias. Formado pela Faculdade de Tecnologia de Botucatu – SP (FATEC), já desenvolveu softwares utilizando a plataforma .NET, Delphi junto com Banco de Dados SQL Server e Firebird. Como experiências profissionais mais recentes, possui em seu currículo sua atuação no Centro de Processamento de Dados da Prefeitura Municipal de Itaí-SP e atualmente compõe a equipe da Coordenadoria Tecnologia da Informação no IFSP – Instituto Federal do Estado de São Paulo em Avaré. Além disso, é colunista mensal da Revista The Club Megazine e é consultor Técnico do The Club. Possui as seguintes certificações: MCP - Microsoft Certified Professional, MCTS - Microsoft Certified Technology Specialist, MCAD - Microsoft Certified Application Developer e  MCSD - Microsoft Certified Solution Developer.


Nenhum comentário:

Postar um comentário