Wiki ADA

Projetos em Engenharia de Computação

Ferramentas do usuário

Ferramentas do site


android-recycler-view

Essa é uma revisão anterior do documento!


Crie listas com RecyclerView

Artigo em construção. Enquanto isso, você pode seguir esse artigo.

Em aplicativos Android, é comum criar telas com listagens de diversas formas possíveis: horizontalmente, verticalmente, em forma de grade, entre outros exemplos. Existem casos que a quantidade de itens é tão grande que o aplicativo demora vários segundos para renderizar-los, causando desconforto no usuário. Dessa forma, entra em cena o RecyclerView, componente padrão de layout de listagens do Android Studio para uso no desenvolvimento nativo de aplicativos Android, o qual utiliza itens “recicláveis” na respectiva View a ser desenvolvida.

O RecyclerView funciona renderizando somente os itens da lista que aparecerão na tela do celular, deixando todos os outros descarregados e assim “reciclando” a listagem. O intuito é poder carregar a quantidade suficiente de itens sem que isso interfira na experiência do usuário durante o uso do app. Apesar da boa intenção, a configuração de um RecyclerView pode não ser tão intuitiva para iniciantes.


Estrutura

O RecyclerView é estruturado em quatro partes:

Todas as quatro partes conversam-se entre si, portanto, deve-se ter em mente a visualização da listagem antes da configuração. A harmonia entre as partes produz um design perfeito para o aplicativo.

LayoutManager

O LayoutManager é a parte que dita o visual da listagem no momento de sua renderização, e é atribuído ao RecyclerView no momento da configuração deste componente. Por exemplo, caso se utilize um LayoutManager do tipo LinearLayoutManager, pode-se criar listas lineares tanto verticais quanto horizontais, sendo essa orientação definida no momento de sua instanciação. Por outro lado, há a existência do GridLayoutManager, que organiza a lista em forma de grade, semelhante a aplicativos padrão de fotos. Por conta do GridLayoutManager criar uma listagem em grade de forma que todos os itens têm a mesma largura e altura, há momentos que se gera desconforto pela informação não encaixar perfeitamente nos itens. Para evitar esse efeito, pode-se utilizar o StaggeredGridLayoutManager, que adapta a altura do item de acordo com o item presente em seu interior e permite um desnível entre os itens laterais, possibilitando um design mais limpo e leve, assim como é no Google Keep.

Adapter

O Adapter trata da forma em que serão organizados os itens da lista a ser exibida, sendo responsável por dizer quantos itens aparecerão na lista, como será o layout dos itens a serem apresentados e qual será a lógica de apresentação de cada item específico. Geralmente, o programador deve criar uma nova classe para ser o Adapter de seu RecyclerView, e essa nova classe deve herdar de RecyclerView.Adapter. Dentro da classe, deve-se implementar obrigatoriamente os métodos onCreateViewHolder, onBindViewHolder e getItemCount. Fica clara a relação do Adapter com o ViewHolder justamente pelo nome dos métodos mencionados.

onCreateViewHolder

Esse método trata do momento da criação do ViewHolder conectado ao Adapter, o qual carregará consigo o layout XML do item da lista. Esse layout será usado na construção de um objeto do tipo View para utilizar posteriormente na construção e retorno do ViewHolder citado. Em resumo: será escolhido um layout específico para representação dos itens da lista e este será conectado ao ViewHolder atrelado a cada item da lista.

onBindViewHolder

Como o próprio nome sugere, esse método tratará o momento que um item da lista aparecer no aplicativo. No momento que o item em questão for vinculado (do inglês bind) à lista, esse método será chamado e executado antes da apresentação dele.

getItemCount

Seguindo a intuitividade, esse método deve retornar o tamanho da lista a ser renderizada. Em praticamente todas as situações, será retornado o tamanho da lista de itens dentro do Adapter.

ViewHolder

A classe ViewHolder será responsável por identificar os componentes de layout de cada item da lista (TextViews, ImageViews e Buttons, por exemplo). Essa classe, que deve herdar obrigatoriamente de RecyclerView.ViewHolder, deve também obrigatoriamente implementar seu construtor, que em praticamente todas as vezes será aplicando o método findViewById em seus objetos de componente de layout locais. Como seu próprio nome sugere, o ViewHolder será um apoio para a View atrelada ao layout do item da lista, este presente como parâmetro no método construtor daquele. Posteriormente, o ViewHolder será usado como meio-termo para endereçar e modificar os componentes do layout do item da lista através dos métodos implementados no Adapter.

Componente RecyclerView

O RecyclerView em si será o objeto que representará a lista a ser apresentada no aplicativo. No layout XML da Activity ou do Fragment, deverá ser adicionado o componente de layout referente ao RecyclerView, além do próprio objeto dentro do código Java. Programaticamente, o LayoutManager e o Adapter serão vinculados ao RecyclerView durante sua configuração. Internamente ao Adapter, o ViewHolder estará atuando na identificação dos componentes de layout de cada item da lista, tratando-os conforme configurado em cada método implementado no Adapter. É assim que se dá a configuração e harmonia entre os componentes do RecyclerView.


Exemplo de implementação

Criando o RecyclerView dentro de sua Activity ou Fragment

Com um projeto Android criado, ao criar uma nova Activity, teremos o código default abaixo dentro da classe java no pacote especificado.

MainActivity.java
package com.exemplo.recyclerview;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
 
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

Além disso, também será criado o arquivo XML com o código default abaixo dentro da pasta res > layout, o qual está “conectado” com o arquivo java acima descrito.

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
 
</android.support.constraint.ConstraintLayout>

Ao abrir o arquivo XML no Android Studio, temos a tela a seguir.

Para fins didáticos, excluiremos o TextView presente no layout e adicionaremos o RecyclerView ao layout. Para isso, basta selecionar o componente RecyclerView em Palette e arrastar para a tela branca.

Será aberto um aviso para confirmar a importação da biblioteca referente ao RecyclerView. Basta clicar em OK para continuar.

Dessa forma, o RecyclerView será importado ao projeto e adicionado ao seu layout que está conectado à sua Activity. Conectando as constraints às laterais de sua tela branca e inserindo a string recyclerViewExemplo como id do RecyclerView adicionado, teremos como resultado a imagem abaixo.

Como resultado, o código XML referente ao layout será o apresentado a seguir.

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
 
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerViewExemplo"
        android:layout_width="395dp"
        android:layout_height="715dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

Instanciando o LayoutManager e vinculando-o ao RecyclerView

Nesse passo, primeiramente iremos referenciar o RecyclerView no código java através da classe representativa do componente e do método findViewById.

MainActivity.java
package com.exemplo.recyclerview;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
 
public class MainActivity extends AppCompatActivity {
 
    //Variável global para referenciar o RecyclerView da interface
    private RecyclerView recyclerViewExemplo;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        //Conectando a classe representativa com o componente de layout
        recyclerViewExemplo = findViewById(R.id.recyclerViewExemplo);
 
    }
}

Posteriormente, iremos instanciar o LayoutManager configurando-o da forma que preferirmos e inserindo no RecyclerView. Nesse exemplo, configuraremos o LayoutManager como sendo do tipo LinearLayoutManager com orientação vertical.

MainActivity.java
package com.exemplo.recyclerview;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
 
public class MainActivity extends AppCompatActivity {
 
    //Variável global para referenciar o RecyclerView da interface
    private RecyclerView recyclerViewExemplo;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        //Conectando a classe representativa com o componente de layout
        recyclerViewExemplo = findViewById(R.id.recyclerViewExemplo);
 
        //Configurando o LayoutManager e inserindo a configuração em nosso RecyclerView
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(
                this,
                LinearLayoutManager.VERTICAL,
                false
        );
        recyclerViewExemplo.setLayoutManager(layoutManager);
    }
}

Definindo o ViewHolder

O ViewHolder, com o papel de apoiador da View, será uma nova classe auxiliar a ser criada. Primeiramente, para que um ViewHolder faça sentido, precisamos criar um layout referente aos itens da lista, tal qual será a base para cada um a ser apresentado.

Primeiramente, vá até res > layout, clique com botão direito na pasta e vá em New > Layout resource file. Uma janela será aberta. Cuidado: isso deve ser feito na pasta layout.

Na janela aberta, escolha um nome para o seu arquivo de layout. Nesse exemplo, será escolhido o nome adapter_itens por questão de didática, mas pode ser escolhido qualquer nome. Em Root element, você pode escolher qualquer layout que preferir. Para que o exemplo se torne mais fácil, iremos escolher o ConstraintLayout.

Após criar o arquivo de layout, crie o seu próprio layout para os itens de sua lista. Você pode pegar um pouco de inspiração na imagem abaixo, mas sinta-se livre para criar algo que seja agradável.

Lembre-se: o layout mais externo deve ter o atributo layout_height com o valor wrap_content. Caso não seja feita essa verificação, há possibilidade dos itens possuírem um tamanho muito grande para o tamanho da tela.

Dica: utilizar LinearLayout ao invés de ConstraintLayout traz resultados melhores nessa parte da configuração do RecyclerView, mas, por questões didáticas, será mantido o uso do segundo.

O código XML referente ao layout desenvolvido acima está mostrado abaixo.

adapter_itens.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
 
    <TextView
        android:id="@+id/textNumeroItem"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="32dp"
        android:layout_marginTop="8dp"
        android:text="Número item"
        android:textStyle="bold"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
 
    <TextView
        android:id="@+id/textDescricaoItem"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="32dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:text="Descrição"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textNumeroItem" />
 
    <TextView
        android:id="@+id/textData"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="32dp"
        android:text="dia/mês/ano"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textNumeroItem" />
</android.support.constraint.ConstraintLayout>

Após criar o layout referente a cada item da lista, será criada a classe auxiliar referente ao ViewHolder. Para isso, vá em java > nome.do.seu.pacote, e, com o botão direito, vá em New > Java Class.

Na janela aberta, coloque um nome para o seu ViewHolder. Neste exemplo, será usado o nome MyViewHolder, mas pode ser utilizado o nome que preferir.

Ao clicar em OK, a classe java será criada com o código abaixo.

MyViewHolder.java
package com.exemplo.recyclerview;
 
public class MyViewHolder {
 
 
}

Essa classe deverá extender de RecyclerView.ViewHolder. Ao adicionar essa herança, o código resultante será o abaixo.

MyViewHolder.java
package com.exemplo.recyclerview;
 
import android.support.v7.widget.RecyclerView;
 
public class MyViewHolder extends RecyclerView.ViewHolder {
 
 
}

Ao adicionar essa superclasse à classe, pode ser reparado que a declaração da classe fica grifada em vermelho. Isso se deve ao fato que se tem a obrigatoriedade de declarar um construtor para essa classe, por conta que essa classe deverá referenciar, dentro de seu construtor, cada um dos componentes de layout inseridos no layout criado nos passos anteriores. Para que isso seja resolvido, clique na lâmpada vermelha que aparece à esquerda, e selecione a opção Create constructor matching super.

O seu código terá como resultado o abaixo.

MyViewHolder.java
package com.exemplo.recyclerview;
 
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;
 
public class MyViewHolder extends RecyclerView.ViewHolder {
 
    public MyViewHolder(@NonNull View itemView) {
        super(itemView);
    }
 
}

Agora, dentro do construtor, referencie todos os componentes de layout que você inseriu no layout criado anteriormente. O código abaixo será referente ao layout sugerido anteriormente.

MyViewHolder.java
package com.exemplo.recyclerview;
 
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
 
public class MyViewHolder extends RecyclerView.ViewHolder {
 
    TextView textNumeroItem, textDescricaoItem, textData;
 
    public MyViewHolder(@NonNull View itemView) {
        super(itemView);
 
        textNumeroItem = itemView.findViewById(R.id.textNumeroItem);
        textDescricaoItem = itemView.findViewById(R.id.textDescricaoItem);
        textData = itemView.findViewById(R.id.textData);
 
    }
 
}

Obs: devemos referenciar através do objeto itemView que é passado por parâmetro ao construtor do ViewHolder. Isso se deve por conta de que somente conseguiremos referenciar os componentes de layout que estão “dentro” do itemView, o qual é do tipo View. Por isso que o ViewHolder é, de fato, um apoio da View. Além disso, em alguns passos adiante, na declaração do Adapter, devemos escolher de forma correta o layout a ser inserido na View a ser criada, para que não haja erros dentro do ViewHolder na hora de referenciar os componentes de layout.

Configurando o Adapter e vinculando o ViewHolder a ele

Para criar o Adapter, devemos criar uma nova classe java e fazê-la herdar de RecyclerView.Adapter<ViewHolder>. Neste exemplo, deve-se criar uma classe com nome AdapterExemplo, e no lugar de ViewHolder da classe que será herdada, será usado MyViewHolder.

Primeiramente, vá até java > nome.do.seu.pacote, clique com o botão direito, vá até New > Java Class.

Concluindo a configuração do RecyclerView e teste

perae.java
public class Perae {
 
    String message;
 
    public Perae(){
        this.message = "perae mano, jaja o artigo fica pronto";
    }
 
    public void aprenderRecyclerView(){
        System.out.println(this.message);
    }
 
}

Referências externas

android-recycler-view.1570193919.txt.gz · Última modificação: 2019/10/04 09:58 por forfs