Tutorial: CRUD em Android com SQLite e RecyclerView (Parte 1)

Fazia tempo que este post estava na minha pauta: como fazer um CRUD em Android com SQLite. Mas antes de começar, vamos a algumas definições:

O que é um CRUD? É um acrônimo para Create, Read, Update e Delete, as quatro operações elementares com bancos de dados relacionais.

O que é SQLite? É o banco de dados compacto mais utilizado no mundo e que já vem com suporte nativo na plataforma Android, como banco de dados local nos smartphones.

Se é a primeira vez que está criando um app para Android, sugiro ler primeiro este post aqui, bem mais introdutório: Android Studio Tutorial.

Certifique-se antes de começar de que você possui o Constraint Layout disponível no seu Android Studio, pois usaremos ele aqui como gerenciador de layout. Se você nunca lidou com ele antes, dê uma olhada neste tutorial primeiro.

Avisos feitos, vamos começar o tutorial!

Veremos neste tutorial:

  1. Criando e explorando o projeto Basic
  2. Criando a tela de cadastro/edição
  3. Preparando a persistência de dados
  4. Cadastrando Clientes
  5. Listando Clientes (em breve)
  6. Atualizando Clientes (em breve)
  7. Removendo Clientes (em breve)

Parte 1: Criando e explorando o projeto Basic

Crie um novo projeto no Android Studio com o nome de AndroidCRUD. Durante o assistente de criação do projeto, escolha como Activity inicial a Basic Activity, aquela que tem o botão de + no canto direito. O resto deixe tudo padrão e avance até o final.

A Basic Activity adiciona uma série de elementos prontos que podemos customizar conforme as nossas necessidades. Nossa estrutura de pastas já começa assim:

Estrutura Inicial
Estrutura Inicial

Se abrirmos a MainActivity veremos que ela já possui um evento onCreate com o seguinte código:

Aqui definimos o arquivo XML de layout que é o activity_main.xml, uma toolbar que ficará no topo da Activity e um botão flutuante (Floating Button) que quando clicado vai disparar uma mensagem genérica na Snackbar (uma barra inferior, tipo um Toast mais moderno).

Mais abaixo, temos o código de invocação do menu que fica no canto superior direito da toolbar azul, o que não vem ao caso olharmos agora.

Já na pasta layout temos o activity_main.xml, que foi referenciado no código Java anterior, e o content_main.xml. Isso porque se olharmos o código do activity_main.xml logo abaixo, poderemos notar que ele usa uma tag include para o outro XML, permitindo um reaproveitamento de elementos de layout, assim como fazemos em tecnologias web:

Este XML serve como uma página-mestra do app, garantindo uma uniformidade entre as telas definindo elementos básicos como a toolbar no topo e o floating button no canto inferior direito. Falando dele, por padrão ele veio com um ícone de email, mas podemos mudar isso facilmente, pois faremos um cadastro de clientes, então queremos um sinal de adição como ícone. Note como faço iso pelo próprio editor de XML do Android Studio na propriedade app:srcCompat do FloatingActionButton como abaixo:

Trocando o ícone
Trocando o ícone

Ainda no XML activity_main, na tag include, vamos colocar um id nela para que possamos alterar o XML que ela referencia através de nosso código Java mais tarde, deixe-o como abaixo (incluindo o visibility):

Já o XML content_main.xml contém o “miolo”, a área central a tela, aqui no caso apenas com um Hello World, que mais tarde iremos alterar:

Agora que já criamos e exploramos a estrutura básica do projeto, vamos em frente!

Parte 2: Criando a tela de Cadastro/Edição

Agora que entendemos que a activity_main.xml será o “esqueleto” de todas telas, e que devemos criar apenas os arquivos XML de “miolo”, podemos adicionar um novo arquivo de layout na pasta correspondente com o nome de content_cadastro e com o root tag ConstraintLayout. Configure a aparência desse layout para que represente um formulário de cadastro como abaixo (ou similar):

Layout de Cadastro
Layout de Cadastro

O código desta tela pode ser obtido abaixo:

Alguns pontos a se considerar aqui são o uso de um RadioGroup por fora dos RadioButtons, para garantir que apenas um deles seja selecionável. E o uso de um Spinner para guardar estados, estes por sua vez devem ser armazenados em um estados.xml dentro da pasta res/values:

Agora, voltando à tela activity_main.xml, vamos adicionar um novo include logo abaixo do anterior, referenciando a content_cadastro.xml, mas com uma visibility oculta:

A ideia é que apenas um dos includes seja visível por vez, iniciando com o id includemain e depois trocando para o includecadastro via código Java, quando o usuário clicar no FloatingActionButton. Para que essa transição ocorra, mude o código do clique do FloatingActionButton na MainActivity.java para o código abaixo, que apenas esconde o includemain (e o botão) e exibe o includecadastro:

Para concluir esta etapa de navegação, a tela de cadastro possui um botão de cancelar que não deve fazer nada especial exceto voltar para a tela anterior. Para programar essa transição, vamos incluir o trecho que manipula o onClick do btnCancelar dentro do onCreate da MainActivity.java:

E para já deixar nosso botão de Salvar parcialmente pronto, vamos criar o código abaixo que manipula o onClick do btnSalvar, também na onCreate da MainActivity.java:

Com isso encerramos a criação da tela de cadastro/edição. Ok, não fizemos nada ainda referente à edição, mas você vai entender mais pra frente.

Parte 3: Preparando a persistência de dados

Agora que temos as telas funcionando, com suas devidas posições e o onClick do botão de Salvar apenas esperando pelo código final, vamos programar algumas classes Java que vão cuidar da parte de persistência de dados no SQLite.

Primeiro, adicione no seu package principal do projeto uma classe DbHelper como abaixo, que cuidará do script de criação e atualização do banco de dados, extendendo as funcionalidades da SQLiteOpenHelper nativa do Android:

O método onCreate dessa classe será chamado automaticamente na primeira vez que for realizada uma conexão com o banco de dados, criando-o com uma única tabela ‘Clientes’ conforme SQL informado em uma String final. Os demais parâmetros posicionados como final no topo da classe são auto-explicativos. Esta é a única responsabilidade que daremos para a mesma.

Agora, crie uma segunda classe que vai representar o nosso cliente de banco de dados, que chamaremos DbGateway (conforme o Design Pattern Gateway), que fará as conexões nesta base que acabamos de codificar (por ora, apenas isso):

Nesse DbGateway eu também usei o Design Pattern Singleton para garantir que exista apenas um cliente de banco de dados único para todo o meu app, uma vez que o SQLite não trabalha muito bem com concorrência e porque múltiplas conexões poderiam consumir recursos demais.

Vamos criar também uma nova classe no nosso projeto, uma que espelhe a tabela Clientes do banco de dados, que chamaremos de Cliente.java, nosso data object:

Nada de demais aqui, apenas um bando de atributos e métodos para usar essa classe como uma estrutura de dados de cliente simples. Os métodos sobrescritos serão usados muito mais tarde neste tutorial.

Agora, para finalizar nossa preparação da persistência de dados, vamos criar uma última classe usando o Design Pattern Data Access Object, a ClienteDAO.java, que é a classe responsável por fazer a tradução dos objetos para o banco de dados e vice-versa, abstraindo acesso à dados para uso das telas mais tarde:

Vamos adicionar novos métodos nessa classe nas etapas seguintes deste tutorial, para de fato fazer as operações do nosso CRUD. Por ora, ela terá apenas um construtor que pega a instância única de DbGateway e deixa guardada em uma variável local para uso posterior.

Você notou que no ClienteDAO e no DbGateway precisamos de um objeto Context? Essa é uma necessidade do SQLite, saber qual o Context em que ele está sendo manipulado para questões como permissões entre outras da arquitetura do Android. Passaremos esse Context facilmente mais tarde.

Parte 4: Cadastrando clientes

Agora que temos tanto as telas quanto à persistência de dados nos esperando, vamos finalmente fazer a nossa tela de cadastro funcionar!

Dentro da classe ClienteDAO.java, crie o seguinte método, que usa a DbGateway.java para pegar a conexão atual com o banco de dados e executar um insert no SQLite com os parâmetros recebidos:

Aqui usei as boas práticas recomendadas na documentação oficial do Android, onde diz que para INSERTs devemos usar o método insert informando o nome da tabela e um map de content values com as colunas e valores que queremos inserir.

Agora, no click do botão de Salvar da content_cadastro, vamos chamar essa nossa classe ClienteDAO.java para executar o método salvar (abaixo eu substituo o bloco inteiro original):

Separei esse código em três grandes blocos: no primeiro, apenas referencio localmente os widgets da interface gráfica. No segundo bloco, carrego variáveis locais com os valores de cada widget. E no terceiro, envio para o ClienteDAO realizar o insert retornando se funcionou ou não, retornando à tela anterior.

Se tudo deu certo, você deve conseguir salvar os dados com sucesso, mas não conseguirá vê-los depois de salvo. No tutorial de testes com Android Studio e no de Engenharia Reversa eu ensino como você pode pegar o arquivo do banco de dados SQLite dentro do simulador Android. No entanto, isso não resolve o nosso problema que é o de não ter programado a listagem (SELECT) de clientes ainda, que é o que faremos na segunda parte deste tutorial ainda esta semana, juntamente com as demais letras do CRUD.

Atenção: caso tenha criado seu banco com algum problema ou já tenha enchido o mesmo com muito lixo e queira começar do zero, você pode ir nas configurações dos eu Android (tanto o simulador quanto um dispositivo físico) e limpar os dados do aplicativo. Se isso não resolver, desinstale o app  e mande rodar novamente pelo Android Studio que ele instalará “zerado”.

A segunda parte deste tutorial pode ser conferida neste link.

Já conhece o meu livro de Android? Clique no banner abaixo para conhecer.

Criando apps para empresas com Android

O que achou desse artigo?
[Total: 21 Média: 4.2]

Publicado por

Luiz Duarte

Pós-graduado em computação, professor, empreendedor, blogueiro, autor, palestrante e programador.

  • Ave Nasci

    No ListView tinhamos o setOnItemClickListener. E no recyclerView. como faço ?
    Quero dar um clique e executar alguma acão