Alura > Cursos de Mobile > Cursos de Android > Conteúdos de Android > Primeiras aulas do curso Recycler View parte 1: listas flexíveis e performáticas

Recycler View parte 1: listas flexíveis e performáticas

Implementação inicial da lista de notas - Introdução

Olá! Sou Alex Felipe, instrutor da Alura e acompanharei você neste curso de RecyclerView Parte 1.

O nosso objetivo será atender o pedido de um cliente, montando uma App chamada Ceep. O objetivo dela é listar notas, que podem ser adicionadas pelo usuário.

O funcionamento da App consiste, basicamente, em clicar no botão "Inserir uma nota", na parte inferior da tela, para abrir um formulário que pode ser preenchido com um título e uma descrição logo abaixo.

Preenchidos o título e a descrição, basta clicar no sinal de visto () no canto superior direito, e a nota estará criada. É uma aplicação bem simples, considerando tudo que já foi estudado nos cursos de pré-requisito, Android I e Android II.

Analisando a base do funcionamento da App, consideraremos a implementação de ListView. Desenvolveremos o projeto nos atentando a uma exigência do cliente de que a aplicação funcione de forma performática, independente da quantidade de itens. Ou seja, o usuário poderá trabalhar com 500, 1.000 ou até 10.000 notas com boa performance.

Durante o curso, notaremos que trabalhar com ListView - desta maneira e neste caso - não é o ideal. Depararemos com alguns lags e algumas quebras. Pensando nessas situações de grandes volumes de dados, utilizaremos uma API mais avançada e performática, em comparação ao ListView, a RecyclerView.

Diferente do ListView, ele trabalha de forma bem bacana com 1.000, 10.000 ou 100.000 dados. Outro aspecto legal do RecyclerView está relacionado ao Layout. Há diversas formas e grids disponíveis para uso. Não exploraremos todas as ferramentas dessa API, algumas relacionadas à animação. Focaremos nas partes de Layout e performance.

Como vimos no Ceep, temos um Layout desenvolvido. Não se preocupe com isso. No curso não será exigido conhecimento específico sobre Layouts, inclusive utilizaremos uma API nova para construí-los, conhecida como ConstraintLayout.

Será disponibilizado um material pronto para download, dispensando o conhecimento prévio da API. Mas, se tiver interesse, na Alura você encontra cursos para aprofundar seus conhecimentos em ConstraintLayouts.

Um detalhe interessante é que, além de RecyclerView e Layout, estudaremos refatoração de código, facilitando a manutenção e a leitura do mesmo — muito importante no cotidiano de quem desenvolve. Durante a implementação do Ceep, utilizaremos também algumas boas técnicas para Android.

Espero que tenha gostado do conteúdo e da proposta! Vamos começar?

Implementação inicial da lista de notas - Criando o projeto

Vamos iniciar o projeto? O primeiro passo será abrir o Android Studio. Na tela inicial, encontramos as opções de ferramentas e a identificação da versão, no caso 3.0.1. Sinta-se à vontade para utilizar versões mais recentes, pois isso não será um problema.

Para criar um projeto, clicaremos na primeira opção, de cima para baixo, Start a new Android Studio project.

Tela inicial Android Studio versão 3.0.1. Apresenta as seguintes opções, de cima para baixo: Start a new Android Studio project; Open an existing Android Studio project; Check out project from Version Control; Profile or debug APK; Import project (Gradle, Eclipse ADT, etc.); Import an Android code sample. No canto inferior direito, encontramos: Configure e Get Help.

Ao clicar, será aberto o Wizard de começo de projeto. Preencheremos o primeiro campo (Application Name) com o nome Ceep, o mesmo da App. Company domain requer o domínio da companhia, no caso, deixaremos preenchido com alura.com.br. Em Project location, selecionaremos o melhor diretório para salvar o projeto.

Embaixo, encontraremos o nome do pacote raiz (Package name) br.com.alura.ceep, que consiste no nome da aplicação somado ao domínio definido. Mais abaixo, um pouco escondido — podemos aumentar a janela para visualizarmos melhor —, temos a opção de ativar suporte para outras linguagens de programação, como C++ e Kotlin. Como utilizaremos Java, não há necessidade de ativá-las. Na sequência, podemos clicar em "Next".

Será aberta outra janela de configuração para definirmos o mínimo de suporte das APIs do Android. Por padrão, encontramos API 15: Android 4.0.3 (IceCreamSandwich), que atende todos os dispositivos, sendo a mínima disponível. Manteremos as definições padrão e clicaremos em "Next".

Janela Target Android Devices, para seleção de forma de fatores e SDK mínimo. Abaixo, encontramos o texto descritivo com a informação de que alguns serviços requerem SDKs adicionais, e que baixos níveis de API atingem mais serviços, mas oferecem menos funcionalidades de API. A pripmeira opção "Phone and Tablet" está selecionada, preenchida com a opção `API 15: Android 4.0.3 (IceCreamSandwich)`. Há um texto explicativo segundo o qual a seleção de `API 15` e posteriores cobre aproximadamente 100% dos serviços. As outras opções, não selecionadas, são: Include Android Instant App Suport; Wear; TV; Android Auto e Android Things.

A próxima etapa seria adicionar Activity, porém não o faremos, pois selecionaremos Add No Activity. Dessa forma, aceleraremos a criação e, caso nos deparemos com algum problema durante o processo, nos concentraremos em resolvê-lo. Evitaremos preocupações com a Activity nesse momento. Feita a seleção, clicaremos em "Finish" no canto inferior direito.

Janela Add an Activity to Mobile. As opções exibidas, da esquerda para a direita, são: Add No Activity (selecionada); Basic Activity; Bottom Navigation Activity e Empty Activity.

Com as configurações aplicadas, o Android Studio executará as tasks do Gradle. Às vezes demora um pouco, principalmente se for a primeira execução.

Assim que o processo for concluído, vamos conferir se deu tudo certo acessando "Project > app > java", à esquerda da tela, ou utilizando o atalho "Alt + 1". No pacote java, encontraremos o esperado:

Sabendo que o projeto foi criado com sucesso, podemos adicionar Activity para criarmos a primeira tela da App, e testar se funciona corretamente.

Selecionaremos o pacote raiz br.com.alura.ceep, no menu à esquerda, e acionaremos o atalho "Alt + insert" para abrirmos opções de novas criações (New). Para agilizar, podemos utilizar o filtro, digitando ac. Nos resultados, encontraremos Activity, que estamos procurando. Clicaremos na seta para a direita e selecionaremos a opção Empty Activity para criarmos uma vazia, considerando que nela desenvolveremos o nosso próprio Layout.

Novamente, encontraremos um Wizard para criar a Activity. Na primeira opção, definiremos um nome. Seguiremos a proposta do cliente, que espera a lista de notas na tela inicial. Portanto, nomearemos a primeira tela como ListaNotasActivity. Na sequência:

Aplicadas as configurações, clicaremos em "Finish".

Começará a criação da Activity. Aguardaremos processo e, quando estiver concluído, haverá um aviso de que a classe R não está compilando. Isso acontece porque ela é acessível via pacote raiz, e estamos no pacote ui.activity.

package br.com.alura.ceep.ui.activity;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class ListaNotasActivity extends AppCompatActivity {

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

Para corrigir, precisamos aplicar import. O aviso sugere o atalho "Alt + Enter" e, após a aplicação, a classe R, que estava com a fonte em vermelho, passará a ficar em branco, indicando que o erro foi corrigido. Se analisarmos o código, abaixo da lista de import, encontraremos:

import br.com.alura.ceep.R;

Agora está tudo certo, como esperamos, compilando corretamente. Selecionaremos activity_lista_notas e usaremos o atalho "Ctrl + B" para abrir o editor visual, no qual encontraremos o Layout vazio. Abaixo, à esquerda, clicaremos em "Text".

Dessa forma, teremos o preview do Layout vazio à direita. Agora que temos a Activity inicial, vamos executar a App para conferir o que acontece, e verificar se ela funciona do modo esperado. Quando nos certificarmos de que tudo está funcionando, daremos continuidade ao desenvolvimento do projeto.

Clicaremos na tela à esquerda da visualização do Layout e utilizaremos o atalho "Alt + Shift + F10". Uma pequena janela de "Run" será aberta para rodarmos a App. Teclaremos "Enter" para confirmar.

Ao rodar, ela buscará um dispositivo disponível. Como nenhum é encontrado, o programa pergunta se desejamos utilizar o emulador Pixel API 26. Selecionaremos e clicaremos em "OK".

Fique à vontade para usar outro emulador, embora se recomende a utilização do mesmo, para obtermos os mesmos resultados visuais do curso. Em outra janela, teremos a visualização da simulação. Note que o Android Studio executou a App sem problemas.

Assim, concluímos a primeira etapa, com a criação da Activity. O próximo passo será implementar a tela inicial, de acordo com as solicitações do cliente.

Implementação inicial da lista de notas - Criando a Activity inicial

Agora, com a confirmação de que a App está rodando sem problemas, continuaremos a análise do desenvolvimento do Layout, de acordo com a proposta do cliente.

Para a segunda tela, foi especificado o que se espera em termos de Layout. Ou seja, para cada elemento, o cliente espera que o título da nota contenha um determinado formato:

Antes de focarmos na questão da performance, precisamos implementar o Layout, nos atentando a diversos fatores. Começaremos acessando "Project > app > res > layout > activity_lista_notas.xml", abrindo a tela inicial que o Android Studio criou, por meio de Activity.

Aumentaremos a visualização do código com o atalho "Ctrl + Shift + F12", e clicaremos em "Preview", à direita, para acompanhar as alterações.

Perceba que, quando criamos a Activity, por padrão, foi colocada a bio root chamada ConstraintLayout. Como citado anteriormente, não será necessário conhecimento sobre essa API.

Se tiver interesse, há um curso da Alura, Layouts Android parte 1: Criando telas com ConstraintLayouts, que aborda conceitos básicos para que você construa Layouts bem interessantes.

A implementação que o cliente solicitou já está pronta e disponível, no padrão do ConstraintLayout. Analisaremos alguns detalhes para entendermos o que foi feito, e não simplesmente reutilizar algo pronto sem entender o procedimento.

Copiaremos, por meio do atalho "Ctrl + C", activity_lista_notas no diretório em que está salvo, e colaremos ("Ctrl + V") em "Project > app > res > layout". Abrirá uma janela de confirmação, nos perguntando se realmente queremos colar o arquivo.

Janela de confirmação de cópia. Contém descrição do diretório do arquivo que será inserido. Estão disponíveis campos de edição de nome do arquivo; de seleção de diretório e de abrir a cópia no editor, que está ativada.

Confirmaremos, clicando em "OK". Será aberta outra janela, informando que estamos colando um arquivo com o mesmo nome de um já existente, e questionando se desejamos sobrescrever. Para confirmar que sim, clicaremos em "Overwrite".

Dessa forma, adicionamos o Layout pronto. No "Preview", notamos que ele já possui uma certa forma.

Preview com o título Ceep no topo e, abaixo, 12 vezes o texto "Unable to find layout: item_nota".

Encontraremos alguns erros, que consertaremos adiante, pois analisaremos passo a passo do que foi implementado nessa tela.

Como dito anteriormente, nesse curso focaremos no uso de ReciclerView, e não na parte de Layout, mas caso haja interesse, recomendo fortemente o curso Layouts Android parte 1: Criando telas com Constraint Layouts, que é bem bacana.

Vamos analisar o que foi feito no código, entendendo, identificando e resolvendo os erros presentes. No topo, encontramos ConstraintLayout. Dentro dele, temos o id de ListView. Se preferir, é possível mudar o padrão. Fique à vontade para modificar o que considerar necessário.

Após a id, temos ListView com definições de largura (width) e altura (height). Note que, mesmo definido como 0dp, elas são visualizadas no "Preview". Isso acontece em função de Match Constraint da ConstraintLayout. Essa propriedade aumenta de acordo com a constraint que será inserida.

Constraints são, basicamente, as marcações de cada lado do respectivo campo, no Layout, que podem ser ajustadas com base em posicionamento sobre elementos. Mas, como dito anteriormente, não nos aprofundaremos nesse assunto.

No último atributo da ListView, tools, encontramos um erro no trecho @layout/item_nota. Esse atributo é visível somente no "Preview" e permite que renderizemos outro Layout, de outro local, diretamente na ListView. Ou seja, nesse trecho, estamos utilizando item_nota, que ainda não inserimos no projeto, e estamos tentando adicionar à ListView para obter o "Preview" deste Layout.

Para corrigir esse erro, podemos aplicar item_nota. Localizaremos o arquivo no respectivo diretório, selecionaremos, copiaremos ("Ctrl + C") e colaremos em "Project > app > res > layout". Clicaremos em "OK", na mensagem de confirmação de cópia de arquivo e, na sequência, veremos a mágica acontecer.

A princípio, no "Preview" será exibido que há um erro de CardView. Resolveremos essa questão adiante. Primeiro, vamos verificar como fica a lista de itens, clicando na aba do arquivo activity_lista_notas.xml. Na visualização, perceberemos que o erro de CardView persiste, porque há tentativa de renderizar o Layout criado, dentro da lista.

Agora que vimos como funciona List Items, colocamos item_nota e constatamos o erro de renderização de CardView pois, sendo uma dependência externa, ainda não o temos dentro do projeto. Vamos resolver esse problema adicionando CardView ao projeto. Utilizaremos o atalho "Ctrl + Shift + Alt + S", para abrir o "Project Structure", com a estrutura do projeto.

Nesse ambiente, o foco é o ajuste de módulos (Modules). À direita da janela, encontramos app. Se clicarmos em cima disto, será aberta uma tela com diversas tabs, indicando o conteúdo do módulo. Aplicaremos ajustes na aba de "Dependencies", para adicionar dependências. Clicaremos no sinal de soma, no canto superior direito da tela, e selecionaremos "1. Library dependency".

No campo de busca, digitaremos cardview e clicaremos na lupa à direita. Ao encontrar o resultado, selecionaremos e clicaremos em "OK".

Resultado cardview `com.android.support:cardview-v7(com.android.support-v7:27.0.2`

Feito isso, encontraremos o cardview na lista de dependências. Há uma peculiaridade que é importante ressaltar: trata-se de uma lib do android.support, ou seja, com suporte para APIs mais antigas. Portanto, é importante prestarmos atenção na versão em uso.

Na lista de dependências, a primeira é da versão v7:26.1.0, enquanto cardview é da versão v7:27.0.2. Essa diferença pode gerar problemas de incompatibilidade no projeto, como erros de compilação e outras surpresas.

Sendo assim, clicaremos em "OK", para que a dependência seja adicionada. Ao mesmo tempo, acessaremos "Project > Gradle Scripts > build.gralde (Module: app)". Dessa forma, entraremos no arquivo de build do módulo e modificaremos a versão do cardview. Inclusive, depois do sync, ocorrerá um erro na aba de activity_lista_notas.xml.

Na aba de app, localizaremos a especificação da versão v7:26.1.0, a qual selecionaremos e copiaremos ("Ctrl + C") para colar no local da especificação da versão do cardview, substituindo-se v7:27.0.2. Em seguida, clicaremos em "Sync Now", no canto superior direito.

Assim, sincronizaremos o Gradle, mantendo a compatibilidade da versão do suporte, e evitando possíveis erros futuros. Deste modo, o problema de @layout/item_nota estará resolvido, e o código está compilando corretamente.

De volta a item_nota.xml, no "Preview", o Layout já adquire a forma que o cliente espera, com título e descrição.

Na sequência, podemos resolver os problemas de activity_lista_notas.xml, para depois lidarmos com os de item_nota.xml.

No "Preview", encontramos a lista devidamente renderizada, com o Layout de item_nota, mas no código ainda temos um erro em View. Essa parte corresponde à sombra, embaixo da lista de itens.

Se sublinharmos View no código, em "Preview" a sombra ficará em destaque. Entre as suas especificações, temos id, largura (width) e altura (height). Inclusive, com a utilização de Match Constraint.

No background, encontramos um erro - o @drawable - que representa o fundo no qual são inseridas as notas, indisponível no projeto. Vamos adicioná-lo, abrindo o diretório em que estão os arquivos e localizando fundo_gradiente_insere_nota na pasta drawable.

Da mesma forma que inserimos os demais arquivos, copiaremos do diretório e colaremos em "Project > app > drawable". Uma janela de seleção será aberta, marcaremos o primeiro drawable sem v24 e clicaremos em "OK".

Janela de seleção de diretório (Choose Destination Directory). Há duas abas: Directory Structure e Choose By Neighbor Class. Na primeira, há duas opções de diretório, dentro da pasta app: `...\app\src\main\res\drawable`  e `...\app\src\main\res\drawable-v24`.

Seremos questionados se realmente desejamos aplicar a configuração. Confirmaremos, clicando em "OK", novamente. Em activity_lista_notas, constataremos que o erro em background foi corrigido, após a inserção de fundo_gradiente_insere_nota, em drawable.

Dando continuidade, encontraremos TextView abaixo de View. Ele também contém Match Constraint, para abranger as laterais do campo de inserção de texto do Layout. A altura (height) está definida como wrap_content, para que o aumento seja ajustado conforme necessário. O padding está definido com 10dp, para que o conteúdo estique um pouquinho.

Todas essas configurações estão de acordo com as solicitações do cliente. Caso queira implementá-las sem utilizar o Layout pronto, fique à vontade. Inclusive, se quiser utilizar outras ferramentas, como Linear Layout ou Relative Layout, não tem problema.

Terminamos a parte da análise do Layout da aba activity_lista_notas.xml. Prosseguiremos, acessando a aba de item_nota.xml, em que não encontramos um View group no topo do código. A princípio, temos somente o CardView, já que é o único item necessário a esse Layout. Portanto, não precisamos nos preocupar em utilizar um View group, como ConstraintLayout.

Há um detalhe: no desenvolvimento do Layout, por padrão, temos o ConstraintLayout. Logo, utilizamos a constraint. Como não precisamos mais disto, apagaremos os trechos que a contêm:

app:layout_constraintBottom_toBottomOf="Parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent">

Se estiver desenvolvendo o seu próprio Layout sem o ConstraintLayout, as Constraints não serão necessárias também.

No início do código do CardView, na parte de largura (width), temos match_parent para pegar as extremidades do pai. Já na altura (height), temos wrap_content para que a altura do campo aumente conforme necessário.

Dentro do CardView, temos outro View group, ConstraintLayout, no qual podemos aplicar as regras referentes a alinhamento, entre outros.

Se aplicarmos Zoom no "Preview", notaremos que o Layout está bem alinhado. O TextView de "Título" está em cima, com o de "Descrição" logo abaixo. Eles estão bem alinhados, como se fosse o LinearLayout, no qual um elemento fica embaixo do outro.

No TextView de "Título", tanto width, quanto height estão configurados com wrap_content, ou seja, aumentarão de tamanho conforme necessário. Abaixo, encontramos os campos preenchidos conforme as solicitações do cliente, como:

tools é, basicamente, um atributo para ativar a visualização no "Preview". No momento de execução da App, o texto não aparecerá, a não ser que tenhamos setado algum valor.

Mais abaixo, temos o TextView da "Descrição". Nesse local, os campos estão preenchidos da seguinte forma:

Não precisamos nos preocupar muito com os detalhes, considerando que preenchemos os campos de acordo com as especificações do cliente.

Assim, estudamos superficialmente a parte de construção do Layout. De novo, justamente para reforçar a ideia, recomendo o curso Layouts Android parte 1: Criando telas com Constraint Layouts, importante para quem trabalha com Android.

Adiante, implementaremos Adapter e modelo para representar as notas, além de executar a App, testando a parte de performance.

Sobre o curso Recycler View parte 1: listas flexíveis e performáticas

O curso Recycler View parte 1: listas flexíveis e performáticas possui 208 minutos de vídeos, em um total de 53 atividades. Gostou? Conheça nossos outros cursos de Android em Mobile, ou leia nossos artigos de Mobile.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Android acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas