Firebase App - Parte 1
| Site: | IFSC |
| Course: | 2025-2 - PROGRAMAÇÃO PARA DISPOSITIVOS MÓVEIS |
| Book: | Firebase App - Parte 1 |
| Printed by: | Guest user |
| Date: | Friday, 19 December 2025, 3:13 PM |
1. Apresentação
Neste livro conheceremos novos componentes avançados para a construção de aplicativos usando o Android Jetpack. Vamos exemplificar o uso dos componentes de arquitetura (Android Arch Components) do Android Jetpack e o uso do Firebase através do aplicativo Lista de Tarefas.
O aplicativo Lista de Tarefas fornece uma maneira de controlar nossas atividades, mostrando uma lista de tarefas e as opções de marcar como concluída. No aplicativo podemos:
- Criar um usuário
- Cadastrar tarefa
- Marcar tarefa como finalizada
- Remover tarefa
Figura 1 Aplicativo
Devido a complexidade desse projeto e a quantidade de recursos novos a serem aprendidos o livro vai ser organizado em duas partes:
- Parte 1 – Sistema de Login. Criação da interface gráfica com Fragmentos, integração com Firebase e cadastro de usuários. Configuração das transições entre as telas (fragmentos) com o componente de navegação (Navigation) .
- Parte 2 - Funcionalidades da lista de tarefas. Implementação de listas com RecyclerView.
Bons estudos!
2. Recursos Envolvidos
No desenvolvimento da primeira parte do aplicativo, vamos usar as seguintes tecnologias:
- Fragments
- Fragments representam partes reutilizáveis para a criação de interfaces gráficas de uma Activity e também podem conter lógica de programação.
- Originalmente, fragments foram criadas para construir interfaces mais elegantes para os tablets. Por exemplo, dado um aplicativo de celular, o mesmo poderia ser construído fazendo o uso de duas telas, logo com a iteração do usuário essas telas seriam sobrepostas quando necessário. No entanto, em um tablet essa construção parecia estranha pois havia muito espaço sobrando na tela do dispositivo. Assim, com o uso de fragments é possível construir uma única tela no tablet que incorpore essas duas telas menores de um celular, de uma única vez.

Figura 2 Representação de Fragments em um Tablet e um Smartphone
- Note que em abas as versões acima, apenas uma Activity estará rodando. No entanto, a versão do tablet faz o uso de dois fragments ao mesmo tempo e na versão do celular cada Activity usa apenas um fragment.
- No projeto usaremos fragments para criar nosso aplicativo com mais de uma tela. Inicialmente serão criados três fragmentos:
- HomeFragment – fragmento para exibir a lista de tarefas através de uma RecyclerView.
- LoginFragment – fragmento para usuário fazer login.
- CadastroFragment – fragmento para cadastrar um novo usuário.
- Ciclo de Vida
- Similiar a uma Activity, um fragmento também possui ciclo de vida. Neste projeto daremos atenção aos métodos onCreate e onCreateView.
- onCreate – método invocado quando um fragmento é criado.
- onCreateView – método invocado após a criação do fragmento para retornar uma View contendo a definição da interface gráfica do fragmento.
- onActivityCreated – método invocado após a criação da atividade do fragmento. Nesse local iremos fazer a vinculação dos dados da ViewModel aos elementos da tela do fragmento.
- Similiar a uma Activity, um fragmento também possui ciclo de vida. Neste projeto daremos atenção aos métodos onCreate e onCreateView.
- Navegação entre Fragmentos
- Neste projeto vamos fazer o uso dos componentes de arquitetura disponível no Android Jetpack (pacote androidx). Entre eles está o novo componente de navegação, Navigation, que oferece uma solução moderna e simples de se implementar, desde a configuração de gráfico de transições para a programação das transições.
- A navegação se refere às interações que permitem aos usuários navegar, entrar e sair de diferentes partes do conteúdo no aplicativo. O componente de navegação do Android Jetpack ajuda a implementar a navegação, desde simples cliques em botões até padrões mais complexos, como barras de aplicativos e a gaveta de navegação.
- RecyclerView, RecyclerViewAdapter e padrão ViewHolder
- Este aplicativo exibe uma lista de contatos com um componente RecyclerView (pacote androidx.recyclerview) – uma lista rolante de itens reutilizável. Para preencher essa lista vamos precisar criar uma subclasse de RecyclerViewAdapter, cuja finalidade é preencher o elemento RecyclerView utilizando dados de um objeto ArrayList.
- Quando o aplicativo atualiza os dados da lista de contatos ele chama o método notifyDataSetChanged do RecyclerViewAdapter para indicar que os dados mudaram. Então, o adaptador notificará o componente RecyclerView para que atualize sua lista de itens exibidos. Isso é conhecido como vinculação de dados (data binding).
- Cada item adicionado à lista envolve a execução do processo de criar novos objetos dinamicamente. Para listas grandes, nos quais o usuário rola rapidamente, a quantidade de itens gera uma sobrecarga que pode impedir uma rolagem suave. Logo, para reduzir essa sobrecarga, quando os itens do componente RecyclerView rolam para fora da tela, vamos fazer a reutilização desses itens de lista para os novos que estão entrando na tela. Para isso, usamos o padrão ViewHolder, no qual criamos uma classe (normalmente chamada ViewHolder) para conter variáveis de instância para as views que exibem os dados dos itens na RecyclerView.
- TextInputLayout
- Os componentes EditText são usados para criar caixas de texto de modo que o usuário possa digitar algum conteúdo. Para ajudar o usuário entender a finalidade da caixa de texto, podemos especificar a propriedade hint (dica) para esse elemento. Isso mostrará uma mensagem dentro da caixa de texto que desaparecerá assim que o usuário começar a digitar o texto. Por causa disso, pode acontecer do usuário esquecer da finalidade do elemento EditText, uma vez que a dica não aparecerá novamente. Para evitar isso, usamos TextInputLayout (pacote com.google.android.material.textfield.TextInputLayout) da Android Design Support Library.
- Em um TextInputLayout, quando o elemento EditText recebe foco, o TextInputLayout anima o texto da dica, mudando seu tamanho original para um menor e exibe-o acima da caixa de texto. Desse modo, o usuário pode digitar os dados e ver a dica ao mesmo tempo.
- FloatingActionButton
- Os botões de ação flutuantes, comumente chamados de FAB (FloatingActionButton), foram introduzidos pelo Material Design e são botões que “flutuam”, isto é, possuem elevação maior que o restante dos elementos da interface gráfica do aplicativo. A partir do Android 6.0, esse componente passou a ser disponibilizado pela Android Design Support Library.
- É comum usar esse botão para uma ação única, mas importante para o aplicativo. Alguns exemplos de seu uso: enviar um email (Gmail) e, no caso da Agenda de Contatos, ir para a tela de adição de um novo contato.
- FloatingActionButton é uma subclasse de ImageView, portanto, é possível usar esse botão para exibir uma imagem. Dessa forma, podemos usar ícones do Material Design nos FAB’s.
- As diretrizes do Material Design sugerem posicionar esses botões a pelo menos 16dp das margens do celular e a pelo menos 24dp das margens em um tablet. Naturalmente, o Android Studio configura esses valores padrões aos botões do projeto, mas nada impede deles serem modificados.
- Material Design Icons
- O Android Studio oferece uma ferramenta chamada Vector Asset para adicionar ao projeto os ícones disponíveis do Material Design. A lista de ícones é grande e abrange desde ícones de navegações, para ações, acessibilidade, arquivos, play e muitos outros.
- Esses ícones são imagens vetoriais capazes de serem redimensionadas para qualquer resolução sem perder a qualidade pois não são exatamente imagens, mas sim definições de formas. Eles também podem ser configurados para diferentes cores.
- Menus
- Menus podem ser adicionados em atividades ou fragmentos. Eles são incluídos na barra do aplicativo (ToolBar) e podem assumir forma de um ícone com uma lista de opções (menu) ou oferecer diretamente ícones para realizar as ações. Esse ícone fica normalmente no lado direita da barra e usa um arquivo do tipo menu.xml para definir seu comportamento.
- Neste projeto iremos configurar um Menu com duas opções: editar e excluir um contato.
- Diretório RES
- Além dos tipos de recursos usados nos projetos 1 (Meu app) e 2 (MiniCalculadora), neste projeto lidaremos com outros tipos de arquivos:
- menu – essa pasta contém os arquivos .xml que definem o conteúdo dos menus da aplicação.
- Além dos tipos de recursos usados nos projetos 1 (Meu app) e 2 (MiniCalculadora), neste projeto lidaremos com outros tipos de arquivos:
- Android Jetpack
- O Android Jetpack é uma coleção de componentes de software Android que buscam facilitar o desenvolvimento de excelentes aplicativos Android. Esses componentes ajudam você a seguir as práticas recomendadas, acabando com os códigos clichê e simplificando tarefas complexas, para que você possa se concentrar na parte do código do seu interesse.
- O Jetpack é composto por bibliotecas de pacotes do “androidx.*”, separadas das APIs da plataforma. Isso significa que ele oferece retrocompatibilidade e é atualizado com mais frequência do que a plataforma Android, garantindo que você sempre tenha acesso às versões mais recentes dos componentes do Jetpack.
- Alguns componentes de arquitetura Android Arch Components:
- Fragment: uma unidade básica de interface gráfica combinável
- ViewModel: gerencia os dados para interface gráfica considerando o ciclo de vida
- LifeCycles: para gerenciar os ciclos de vida de atividade e fragmentos
- LiveData: para manipular as informações do banco de dados
- Room: biblioteca para facilitar o acesso ao banco de dados SQLite
Nos próximos partes do projeto será documentado de maneira mais profundos os recursos envolvidos em cada etapa.
3. Criando o projeto
Para a construção deste projeto devemos fazer o uso de uma nova template para a criação da atividade principal e os fragmentos. Dessa forma, siga os passos abaixo para a criação do projeto base da Lista de Tarefas.
- Abra o Android Studio e clique na opção Start a new Android Studio Project na tela de abertura ou, caso já exista um projeto em aberto, clique em File > New > New Project
- Procure pela template "Basic Views Activity":
- Na próxima janela configure o nome do projeto como Lista de Tarefas e modique o local do projeto se achar necessário. Selecione a linguagem de programação Java e API 24. Clique em Finish.
4. Firebase
Para desenvolver o aplicativo vamos precisar um novo projeto na plataforma do Firebase e adicionar os recursos envolvidos. Todos esses preparativos serão demostradas nos próximos capítulos.
4.1. O que é Firebase
O Firebase é uma plataforma de serviços que permite o rápido desenvolvimento de aplicativos. Esses serviços podem ser de autenticação, login social, banco de dados em tempo real, análise de dados entre outros.
Estes serviços contam com o suporte do Google e podem ser usados gratuitamente com um limite de cota. Após o limite, o usuário deve pagar para a continuação do serviço.
No nosso aplicativo vamos usar o serviço de Realtime Database. Trata-se de um banco de dados NoSQL hospedado na nuvem. Com ele, você armazena e sincroniza dados entre os seus usuários em tempo real.
Também iremos usar o serviço de Autenticação com provedor de acesso via email/senha.
4.2. Criando um projeto Firebase
Para um aplicativo poder usufruir dos serviços do Firebase é necessário criar um projeto dentro da plataforma. Para criar um projeto é necessário usar uma conta Google. Acesse o site oficial ou o link abaixo para entrar na página do console e siga os passos abaixo:
https://console.firebase.google.com/
Com a página aberta localize a opção Adicionar Projeto.
(Passo 1) Siga os passos a seguir informando o nome do projeto e clique em Continuar.
(Passo 2) Este passo acaba sendo opcional onde o usuário pode ativar os recursos do Google Analytics ou não. Isso irá permitir visualizar estatística e gerar relatórios. No caso do nosso aplicativo não é necessário ativar estes recursos, portanto desmarque a opção padrão e clique em Criar Projeto.
Aguarde o processo de criação e clique em Continuar.
4.3. Configurando o projeto Firebase - Realtime Database
Com o projeto criado agora é possível adicionar serviços. Para tanto, use o menu lateral para abrir a opção Criação e escolher Realtime Database. Na página que irá abrir clique em Criar banco de dados.
Na criação do banco de dados deixa a opção padrão de região para usar o servidor dos Estados Unidos e clique em Próximo.
Na configuração das regras de segurança escolhe a opção de testes. Para um aplicativo real seria necessário adicionar algumas regras para proteger as informações de acesso não autorizado, mas o nosso aplicativo será simples e de aprendizado portanto ignore as medidas de segurança. Cliquem em Ativar para finalizar a criação do banco de dados.
4.4. Configurando o projeto Firebase - Autenticação
Vamos repetir novamente o processo e adicionar o serviço de Autenticação.
Para tanto, use o menu lateral para abrir a opção Criação e escolher Authentication
Após adicionar o novo serviço clique nele no meu lateral e procure pela aba "Método de Login"
Adicione como provedor "E-mail/Senha"
5. Configurações iniciais do projeto
Nesta primeira parte do projeto vamos construir o desenho da interface gráfica e a configuração dos recursos necessários para a construção do aplicativo.
Vamos realizar as seguintes etapas:
- Integração ao Firebase com o Android Studio
- Criação das classes e fragmentos
- Configuração da classe principal
5.1. Template Basic Views Activity
Diferente dos projetos anteriores, desta vez utilizamos o template 'Basic Views Activity'. Essa template oferece uma estrutura básica e bem completa para iniciar o desenvolvimento de um aplicativo, com várias configurações pré-definidas.
Esse ponto de partida já vem configurado com uma atividade principal, dois fragments e um menu de navegação. A atividade principal funciona como a base do aplicativo, enquanto os fragments, que são componentes de interface responsáveis por diferentes seções do app, representam cada tela. Fragments são ideais para dividir a interface de forma modular, facilitando a navegação entre diferentes partes do aplicativo e melhorando a experiência em telas de vários tamanhos. Com essa estrutura, mudar de um fragmento para outro é fácil, especialmente com o componente de navegação do Android Jetpack, que organiza o fluxo de transição entre telas de maneira visual, prática e sem código excessivo. Assim, é possível configurar as transições e passar dados entre fragments com facilidade, garantindo uma navegação fluida e consistente.
Se você abrir o arquivo activity_main.xml observará um esqueleto para a aplicação. No topo uma ToolBar e no corpo um container para mostrar os fragmentos nav_graph.xml. Dessa forma, é justo dizer que não vamos mexer no layout da atividade principal, mas sim nos fragmentos individuais.
A Toolbar também já está configurada, exibindo automaticamente o título da tela atual e possibilitando a adição de botões ou opções de menu. Isso permite uma interface mais intuitiva, onde o usuário sabe em qual seção do aplicativo está e tem acesso rápido a funções importantes. Com essa template, é simples personalizar a Toolbar e gerenciar as opções de menu, adicionando ou removendo itens conforme necessário.
Essa estrutura básica é um excelente ponto de partida, já que diversas necessidades comuns do app estão previamente configuradas, permitindo focar nas funcionalidades específicas do projeto e simplificando o desenvolvimento.
5.2. Integração com o Firebase
Dentro do Android Studio existem diversas ferramentas que nos ajudam a lidar com o Firebase. Vamos usar esse "Assistente" para conectar a um projeto Firebase, baixar os arquivos de configuração e configurar a SDK.
Com seu projeto no Android Studio aberto vá no menu Tools -> Firebase
A janela que se abrirá a direita é o "Firebase Assistant", através dessa ferramenta conseguiremos configurar rapidamente a integração do Firebase ao projeto.
Primeiramente, escolhe qual serviço será configurado. No nosso projeto vamos usar a Autenticação e o Realtime Database. Iremos ilustrar a primeira opção, siga os mesmos passos para adicionar o outro serviço.
Clique em Autenticação e escolha a opção "Custom Authentication", escolha sempre a opção sem "java" pois queremos a biblioteca do Kotlin.
Siga os passos do assistente para terminar a configuração do Firebase. O Assistente faz o download automático de arquivos necessários ao projeto, configura chaves e mostra exemplos de código de como implementar as funcionalidades.
5.3. Criação das classes do aplicativo
Para a configuração inicial do aplicativo, vamos primeiramente remover alguns arquivos pré-criados e criar novos fragmentos.
- Para tanto remova primeiramente os arquivos FirstFragment.kt e fragment_first.xml
- Remova também SecondFragment.kt e fragment_second.xml
- *Isso provavelmente quebra o aplicativo mas iremos refazer as configurações da atividade principal e da navegação logo a seguir.
Use o botão direito sobre os arquivos de projeto e procure a opção New -> Fragment -> Fragment (black).
Use esta interface do Android Studio para criar três fragmentos: HomeFragment, LoginFragment e CadastroFragment.
O resultado final deve ser a seguinte estrutura de arquivos.
Crie também uma classe chamada Usuário.
O projeto deve estar configura com as seguintes classes:
5.4. Atividade Principal
Nesta seção vamos mostrar algumas modificações na atividade principal bem como explicar seu código inicial.
Primeiramente realize algumas modificações nos seguintes arquivos.
activity_main.xml
Remova o component FAB (Float Action Button) pré-criado
MainActivity.kt
Remova o trecho de código que faz referência ao FAB no método onCreate. Em outro momento vamos fazer a implementação desse tipo de botão.
Use como base o seguinte código:
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
val navController = findNavController(R.id.nav_host_fragment_content_main)
appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
return when (item.itemId) {
R.id.action_settings -> true
else -> super.onOptionsItemSelected(item)
}
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment_content_main)
return navController.navigateUp(appBarConfiguration)
|| super.onSupportNavigateUp()
}
}
Nesta versão avançada da atividade principal, adicionamos novas configurações e métodos. Vamos detalhar cada parte.
No método onCreate, configuramos o suporte à Toolbar com o método setSupportActionBar, onde referenciamos a Toolbar definida no arquivo activity.xml. Esse recurso permite que a Toolbar atue como uma ActionBar, que é a barra de ação no topo da tela.
O objeto appBarConfiguration é utilizado para gerenciar as ações e o comportamento da Toolbar com base nas configurações de navegação, facilitando o uso de ícones e o controle do botão de "voltar" conforme o fluxo do aplicativo. O método onSupportNavigateUp também auxilia nesse processo.
Utilizar uma Toolbar (ou ActionBar tradicional) é essencial para adicionar menus e ações globais ao aplicativo. Para inserir um menu, implementamos dois métodos: onCreateOptionsMenu e onOptionsItemSelected. O primeiro carrega um arquivo XML com a estrutura do menu, enquanto o segundo gerencia os eventos de cada item, determinando as ações a serem tomadas quando o usuário interagir com o menu. Mesmo que o menu não seja customizado agora, essas configurações já estão prontas para futuras atualizações.
Vale destacar que o menu adicionado na Toolbar da atividade principal será exibido em todos os fragments (ou telas) do app, tornando-se um elemento consistente e acessível em toda a interface. Isso garante uma navegação intuitiva, pois o menu principal estará sempre disponível, independentemente da tela onde o usuário se encontra.
6. Navegação
Neste projeto vamos fazer o uso do componente Navigation para configurar a transição das telas. Para tanto precisamos primeiro criar um novo gráfico de navegação e criarmos as transições entre as telas. Também precisamos configurar a atividade principal e programar as ações dos botões.
6.1. Criando um grafo de navegação
Observação: Como usamos a template Basic Views Activity, o grafo de navegação já está criado e podemos pular essa seção. Contudo, deixo aqui como material de referência
Como criar um grafo de navegação
Para criar o grafo de navegação precisamos adicionar um novo recurso no projeto. Para tanto, clique com o botão direito sobre a pasta res e selecione New -> Android Resource File.

Na próxima janela preencha o nome do recurso como nav_graph e selecione o campos Resouce type como Navigation. Clique em OK.

Provavelmente, será notificada uma janela de aviso dizendo para adicionar as dependências do novo componente ao projeto, clique em OK e aguarde. O componente Navigation pertence ao pacote androidx.navigation é deve ser adicionado ao projeto. Se você seguir as orientações do Android Studio isso ocorrerá automaticamente.

Com a nova biblioteca uma nova pasta para armazenar grafos de navegação foi criada. Se tudo estiver certo, ao abrir o arquivo nav_graph, localizado na pasta res/navigation será mostrada a seguinte interface gráfica.

A navegação pode ser configurar via arquivo xml ou graficamente, por simplicidade, iremos ilustrar graficamente como fazer o processo passo a passo. Para o projeto da Lista de Tarefas vamos adicionar primeiramente as telas dos fragmentos e depois fazer as transições entre elas.
6.2. Configurando o grafo
Para modificar o grafo de navegação abra o arquivo nav_graph.xml localizado na pasta res -> navigation.
Inicialmente o grafo está desconfigurado porque removemos os fragmentos pré-criados da template. Para tanto vamos primeiramente remover as configurações antigas e deixar o grafo em branco. Selecione as telas antigas na janela Component Tree e remova-as.
Vamos adicionar a primeira tela como o HomeFragment e consequentemente configurar ela como a tela inicial. A tela inicial pode ser configurada manualmente, mas como o grafo está em branco automaticamente ele vai definir a tela inicial como a primeira tela adicionada a navegação.
Clique no botão ilustrado na figura para adicionar um novo destino (New Destination) e selecione o fragmento principal do nosso projeto.

As possíveis telas serão mostradas como opção de destino. Selecione main_fragment para adicionar a tela ao grafo.
Após adicionar o fragmento principal o grafo se apresentará da seguinte forma, observe que está anotado Start mostrando que a tela principal da navegação será o fragmento adicionado.
Repita os passos anteriores e adicione as demais telas ao grafo. Como resultado final, após organizar a posição das telas você poderá ter a seguinte tela.
A próxima etapa é configurar as possíveis transições de tela pois a navegação se dará por meio das transições configuradas nesse momento. Assim selecione uma tela e clique sobre a bolinha azul que aparece na borda da tela, segure e clique na tela a qual será o destino da transições. Segue a ilustração de como fazer a transição do fragmento home para o fragmento de login:
Certifique de criar as seguintes transições:
- Transição do fragmento home ao fragmento de login
- Transição do fragmento login ao fragmento de cadastro
- Transição do fragmento cadastro ao fragmento home
Como resultado final teremos o seguinte grafo:
Por questão de simplicidade iremos omitir opção avançadas da navegação como animações e definição de argumentos, assim isso é tudo que você precisa fazer para terminar a configuração da transição das telas. Cada transição adicionado foi configurada automaticamente com o nome das telas origem e destino como: action_homeFragment_to_loginFragment, action_loginFragment_to_cadastroFragment e action_cadastroFragment_to_homeFragment. Através do nome da ação, o NavController consegue efetuar a navegação entre as telas. Na próxima seção vamos ver como programar os eventos para chamar essas transições.
7. Desenhando as telas do aplicativo
Nesta etapa vamos criar e configurar os layouts das telas do aplicativo. O projeto Lista de Tarefas possui três telas: a tela principal exibirá uma lista de contatos, a tela de login servirá para a autenticação do usuário e a tela de cadastro configura um novo usuário ao sistema.
7.1. Layout Tela Inicial
A tela inicial do aplicativo será o fragmento Home. Nesta tela vamos mostrar a lista de tarefas mas na primeira versão do app a tela inicial mostrará apenas uma informação de login para depuração.
Dessa forma, siga as etapas abaixo para a configuração da tela de contatos:
- Abra o arquivo fragment_home.xml em modo texto e substitua o ConstraintLayout para FrameLayout.
- Apague o elemento TextView pré-definido
- Adicione uma TextView e configure seu id para loginTextView
- Adicione um Button e configure seu id para logoutButton
- Configure o posicionamento dos elementos para ficar como:
7.2. Layout Tela de Cadastro
No fragmento de Cadastro vamos criar um formulário para o usuário preencher com seus dados. Nesta tela vamos usar TextInputLayout, uma maneira mais elegante de criar entradas de texto com as diretrizes do Material Design.
Abra o arquivo fragment_cadastro.xml e realize as seguintes alterações:
- Apague a TextView criada automaticamente
- Adicione um LinearLayout e configure sua orientação para a vertical e layout_height para wrap_content.
- Adicione ao LinearLayout quatro elementos TextInputLayout, aba Text. Observe que para cada novo elemento será criado também uma EditText.
- Para cada TextInputLayout adicionado, configure as propriedades id como detalhado a seguir e crie uma propriedade hint adequada. Deixe a propriedade hint da EditText em branco senão uma se sobressai a outra.
- ids: nomeTextInputLayout, telefoneTextInputLayout, emailTextInputLayout e senhaTextInputLayout
- layout_height:wrap_content
- Adicione um Button e configure a propriedade id como cadastrarButton e adicione um recurso string para o texto do botão; "Cadastrar"
Use como base a figura a seguir:
Configurando a entrada de texto
- Selecione a EditText dos elementos nomeTextInputLayout, telefoneTextInputLayout e emailTextInputLayout para configurar a propriedade imeOptions para actionNext. Com essa configuração ficará mais fácil para o usuário preencher os dados usando o teclado.
- Selecione a EditText do último elemento, senhaTextInputLayout, e configure a propriedade imeOptions para actionDone. Com essa configuração finalizamos o preenchimento e o teclado irá se esconder quando o usuário clicar em prosseguir.
- Configure cada EditText para um tipo de dado específico. Isso ajuda no preenchimento dos dados pelo usuário. Assim, modifique a propriedade inputType como:
- EditText do nomeTextInputLayout – selecione tipo text, variação textPersonName e textCapWords (coloca automaticamente letras maiúsculas)
- EditText do telefoneTextInputLayout – selecione phone
- EditText do emailTextInputLayout – selecione text e variação textEmailAddress
- EditText do senhaTextInputLayout – selecione text e variação textPassword
As mudanças aplicadas não modificam a aparência do aplicativo mas sim sua usabilidade. O uso correto das propriedades imeOptions e inputType tornam a experiência do usuário mais agradável com o teclado virtual refletindo as configuração adequada.
7.3. Layout Tela de Login
No fragmento de Login vamos criar um formulário para o usuário preencher com seu usuário e senha . Nesta tela vamos usar TextInputLayout novamente.
Abra o arquivo fragment_login.xml e realize as seguintes alterações:
- Apague a TextView criada automaticamente
- Adicione um LinearLayout e configure sua orientação para a vertical e layout_height para wrap_content.
- Adicione ao LinearLayout dois elementos TextInputLayout,
- Para cada TextInputLayout adicionado, configure a propriedade id como detalhado a seguir e crie uma propriedade hint adequada. Deixe a propriedade hint da EditText em branco senão uma se sobressai a outra.
- ids: emailTextInputLayout2 e senhaTextInputLayout2
- Adicione um Button e configure a propriedade id como loginButton e adicione um recurso string para o texto do botão; "Login"
- Adicione um Button e configure a propriedade id como gotoCadastroButton e adicione um recurso string para o texto do botão; "Cadastrar novo usuário".
- Modifique a propriedade layout_width para match_parent e você obterá o visual abaixo:
Use como base a figura a seguir:
Configurando a entrada de texto
Selecione a EditText do elementos emailTextInputLayout e configurare a propriedade imeOptions para actionNext. E senhaTextInputLayout para actionDone.
Configure cada EditText para um tipo de dado específico. Isso ajuda no preenchimento dos dados pelo usuário. Assim, modifique a propriedade inputType como:
- EditText do emailTextInputLayout – selecione text e variação textEmailAddress
- EditText do senhaTextInputLayout – selecione text e variação textPassword
8. Programando Login com Firebase
Nas próximas seções, apresentaremos todas as etapas para implementar o login com e-mail e senha utilizando o Firebase. Além disso, mostraremos como armazenar os dados do usuário em um documento no Firebase, no caminho designado como "usuarios". O sistema armazenará os dados de cada usuário com o caminho "usuarios/uui", onde uui é o código único de usuário gerado pelo sistema de autenticação do Firebase.
8.1. Classe HomeFragment
O fragmento da tela inicial é a primeira janela exibida no aplicativo. Nesta versão inicial, ele apresenta apenas informações básicas do usuário. Abaixo, segue o código completo:
package ...
import ...
class HomeFragment : Fragment() {
private lateinit var mAuth: FirebaseAuth //acessa os recursos de autenticação do Firebase
private lateinit var loginTextView: TextView
companion object {
fun newInstance() = HomeFragment()
}
private val viewModel: HomeViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// TODO: Use the ViewModel
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
//salva em uma variável o layout gerado do arquivo xml
val view = inflater.inflate(R.layout.fragment_home, container, false)
//acessa o componente loginTextView da tela carregada
loginTextView = view.findViewById(R.id.loginTextView)
//acessa o componente logOutButton da tela carregada
val logOutButton = view.findViewById<Button>(R.id.logOutButton)
//adiciona a ação de logout no clique do mouse
logOutButton.setOnClickListener{
mAuth.signOut()
}
return view
}
override fun onStart() {
super.onStart()
//inicializa o serviço de autenticação do Firebase
mAuth = Firebase.auth
//obtem os dados do usuário atual
val currentUser = mAuth.currentUser
//verifica se o usuário existe
if (currentUser != null) {
Log.d("TODO2024", "Usuário logado: " + currentUser.email)
loginTextView.text = "Usuário:" + currentUser.email
//getTarefas()
}
//caso contrário encaminha para a página de login
else {
Log.d("TODO2024", "Usuário deslogado")
findNavController(requireView()).navigate(R.id.action_homeFragment_to_loginFragment)
}
}
}
A variável mAuth utiliza a palavra-chave lateinit, que permite declarar o objeto sem inicializá-lo imediatamente, informando ao Kotlin que ele será instanciado no futuro. Faremos essa inicialização no método onStart. A outra variável, loginTextView, será usada como referência ao componente de texto na interface da tela inicial, exibindo informações básicas do usuário para testes e depuração.
Ciclo de Vida de Fragmentos
Assim como atividades, fragmentos possuem um ciclo de vida próprio, mas com algumas diferenças. Eles são gerenciados e destruídos pelo sistema Android conforme necessário, o que significa que nem sempre usamos o método onCreate para configurações iniciais. Em vez disso, usamos onCreateView para definir a interface gráfica e realizar as configurações necessárias para o fragmento.
Método onCreateView
O método onCreateView é responsável por inflar (carregar) o arquivo XML da interface gráfica e retornar essa visualização para o sistema. No entanto, como precisamos acessar elementos específicos da UI, criamos uma variável view para armazenar a interface carregada, permitindo que possamos referenciar componentes específicos, como o botão logOutButton e a textview loginTextView. Com o objeto logOutButton em mãos, configuramos um listener de clique que chama o método signOut() do objeto mAuth, deslogando o usuário do sistema. O objeto mAuth fornece acesso a todos os métodos necessários para a autenticação no Firebase, permitindo ações como login, logout, recuperação de senha e outros.
Método onStart
É recomendado realizar configurações de persistência e inicializar objetos de autenticação no método onStart, que é chamado toda vez que o fragmento é exibido novamente após uma pausa. Assim, neste método inicializamos o objeto de autenticação mAuth para garantir acesso aos serviços do Firebase. Em seguida, verificamos se existe um usuário logado. Caso contrário, redirecionamos o usuário para a tela de login.
Navegação entre Telas
Para realizar a navegação entre telas, utilizamos um objeto NavController. O NavController permite a transição de fragmentos conforme as ações configuradas no gráfico de navegação do projeto. Para abrir a tela de login, por exemplo, basta chamar o NavController com a ação configurada no XML de navegação. Esse processo é simples e requer apenas uma linha de código, tornando a navegação entre fragmentos prática e eficiente. Para usar a navegação no Android com Kotlin, é importante configurar o gráfico de navegação no XML e associar as ações no NavController ao evento desejado, como o clique de um botão.
Exibindo Dados do Usuário
Caso exista um usuário logado, extraímos as informações desse usuário e exibimos no componente loginTextView da tela inicial. Isso permite verificar e testar dados básicos, garantindo que o sistema de login e o armazenamento de informações estão funcionando conforme esperado.
8.2. Classe LoginFragment
O fragmento de tela de Login é responsável por receber as credenciais do usuário e encaminhar a autenticação para o serviço do Firebase. Na implementação deste código, vamos usar um recurso avançado, chamado View Binding (Vinculação de Visualização), que facilita a manipulação dos componentes da interface de um fragmento ou atividade. Além disso, a autenticação no Firebase será realizada de forma assíncrona, permitindo uma experiência fluida ao usuário ao processar as respostas sem bloquear a interface.
Vinculação de Visualização (View Binding)
View Binding é uma funcionalidade do Android que simplifica o acesso aos elementos da interface definidos em XML. Com ele, não precisamos mais utilizar findViewById para acessar cada componente, evitando erros de null e aumentando a segurança do código. Para habilitar View Binding, basta ativá-lo no arquivo build.gradle do projeto. A partir daí, o Android Studio gera automaticamente uma classe de vinculação para cada layout XML, cujo nome segue o padrão NomeDoArquivoLayoutBinding. No fragmento de login, ao invés de acessar diretamente os elementos da interface, faremos referência a eles por meio da classe de vinculação, proporcionando uma navegação e manipulação mais segura e organizada dos elementos.
Como usamos a template Basic Views Activity neste projeto, a função view-binding já está ativa e podemos pular direito para a programação do fragmento.
Programação Assíncrona com Firebase
Ao usar o Firebase para login, o processo ocorre de forma assíncrona para que o aplicativo continue respondendo aos toques e ações do usuário. A programação assíncrona em Android usa listeners (ouvintes) que monitoram a conclusão de uma tarefa. No Firebase, métodos como signInWithEmailAndPassword retornam uma tarefa assíncrona e permitem adicionar ouvintes com o método addOnCompleteListener. Esse ouvinte verifica quando o processo é concluído e, dependendo do sucesso ou falha da operação, toma as ações apropriadas — como redirecionar o usuário para a tela principal ou exibir uma mensagem de erro.
Este fluxo assíncrono é essencial, pois evita que a interface gráfica congele durante a autenticação, garantindo uma experiência de usuário suave.
Abaixo, segue o código completo:
package ...
import ...
class LoginFragment : Fragment() {
//binding das views automatizado
private var _binding: FragmentLoginBinding? = null
private val binding get() = _binding!!
//firebase
private lateinit var mAuth: FirebaseAuth //acessa os recursos de autenticação do Firebase
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d("TODO2024","app ligou a login")
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
//configura a vinculação
_binding = FragmentLoginBinding.inflate(inflater, container, false)
//adiciona uma ação ao botão de login
binding.loginButton.setOnClickListener {
fazerLogin()
}
//adiciona uma ação ao botão de ir para cadastro
binding.gotoCadastroButton.setOnClickListener{
findNavController(requireView()).navigate(R.id.action_loginFragment_to_cadastroFragment)
}
//inicializa firebase
mAuth = Firebase.auth
// Inflate the layout for this fragment
return binding.root
}
fun fazerLogin() {
val usuario = binding.emailInputLayout2.editText?.text.toString().trim()
val senha = binding.senhaInputLayout2.editText?.text.toString().trim()
mAuth.signInWithEmailAndPassword(usuario, senha)
//Método assíncrono para lidar com a resposta da solicitação
.addOnCompleteListener { task ->
if (task.isSuccessful) {
Log.d("TODO2024", "Login efetuado com sucesso indo para home")
findNavController(requireView()).popBackStack()
} else {
Log.w("TODO2024", "Falha ao fazer Login: ", task.exception)
}
}
}
}
Método onCreateView
O método onCreateView implementa a configuração inicial do view-binding na primeira linha. Após, o carregamento do arquivo FragmentLoginBinding o objeto binding vai conter todas as referências aos componentes da UI do arquivo de layout.
Com o objeto binding acessamos os dois botões da tela e adicionamos um evento para fazer o login e outro para encaminhar a tela de cadastro. Também inicializamos o objeto mAuth para uso posterior.
No retorno deve ser escrito binding.root o que equivale a chamar o método getRoot(), fornecendo uma referência da visualização raiz do arquivo de layout correspondente. Neste caso específico, o FrameLayout que criamos no arquivo fragment_login.xml.
Método fazerLogin
Vamos realizar a autenticação no Firebase utilizando e-mail e senha com o método signInWithEmailAndPassword do objeto mAuth. Esse método faz uma requisição à API do Firebase, e a resposta não é imediata; por isso, precisamos usar programação assíncrona para não bloquear a interface do usuário durante a autenticação.
O próprio Firebase oferece suporte para programação assíncrona. Podemos implementar facilmente um método para lidar com a resposta do evento addOnCompleteListener. Esse evento recebe um objeto task que contém o resultado da autenticação (AuthResult). Com ele, verificamos se a operação foi bem-sucedida usando um fluxo de decisão, que nos permite escolher a ação adequada para cada situação.
- Em caso de sucesso: o usuário é direcionado de volta à tela inicial. Diferente da navegação para uma nova tela, onde informamos explicitamente uma transição, retornar à tela anterior é mais simples e pode ser feito com o método popBackStack do NavController.
- Em caso de falha: registramos uma mensagem de log com o erro. Essas mensagens podem ser visualizadas no LogCat do Android Studio, uma ferramenta útil para diagnosticar problemas. Se o Firebase estiver mal configurado, a conexão de rede apresentar problemas ou houver algum outro erro, o log exibirá informações úteis para corrigir a questão.
8.3. Classe Usuário
Nosso sistema utiliza o serviço de autenticação do Firebase para login de usuários. No entanto, muitas vezes precisamos salvar informações adicionais do usuário para atender às necessidades do aplicativo. Para isso, vamos armazenar esses dados na Realtime Database do Firebase em um documento chamado "usuários", onde cada usuário cadastrado no sistema terá suas informações salvas. Para identificar cada usuário de maneira única, utilizaremos seu código UUID.
Para salvar os dados, criamos uma classe de dados em Kotlin que representará um objeto Usuário no Firebase. Vamos então implementar a classe Usuario, contendo propriedades como nome, telefone e e-mail:
package ...
data class Usuario(val nome: String="", val telefone: String="", val email: String="") {
}
Essa implementação é simples, mas existem dois pontos importantes a considerar:
- Senha não salva no banco de dados: Como o Firebase é responsável pela autenticação, ele já gerencia as senhas dos usuários de forma segura. Por isso, não precisamos (nem devemos) salvar a senha no banco de dados, pois o próprio serviço de autenticação lida com a proteção e gerenciamento desse dado.
- Construtor padrão: É necessário que nossa classe Usuario tenha um construtor com valores padrão, como mostrado. Cada propriedade é inicializada com um valor em branco para que o Firebase possa "serializar" (ou seja, converter o objeto em um formato que possa ser armazenado). Se não houver um construtor padrão, o Firebase não conseguirá realizar o salvamento do objeto, resultando em erros na operação.
Nova sintaxe - data class
No Kotlin, uma data class é uma classe especializada para armazenar dados de forma eficiente. Quando você declara uma classe como data, o compilador automaticamente gera uma série de funcionalidades úteis, como métodos para comparação, exibição e cópia, o que economiza muito código e facilita o trabalho com objetos voltados ao armazenamento de informações.
Utilizar uma data class torna a leitura e gravação de dados mais prática, uma vez que a classe já possui métodos toString(), copy(), e outros que ajudam na manipulação de dados. Além disso, data class facilita a serialização e desserialização dos dados no Firebase, pois a estrutura já é projetada para armazenar informações e não precisa de métodos adicionais para isso. A data class facilita a conversão para e a partir do formato JSON, usado internamente pelo Firebase, sem necessidade de configuração adicional, o que ajuda na simplicidade e manutenção do código.
Não é obrigatório usar data class para trabalhar com o Firebase Realtime Database no Kotlin. No entanto, ela é uma escolha conveniente e recomendada, pois simplifica o código e facilita a manipulação de objetos de dados que representam documentos ou registros.
8.4. Classe CadastroFragment
O fragmento de tela de Cadastro é responsável por registrar um novo usuário no sistema, realizando duas tarefas principais: criar uma conta no serviço de autenticação do Firebase com o e-mail e senha fornecidos e salvar os dados do usuário no documento "usuarios" do Realtime Database.
Para a implementação, utilizaremos o recurso de View Binding, assim como os objetos da biblioteca Firebase: FirebaseAuth para autenticação, FirebaseDatabase para o banco de dados e DatabaseReference para a referência ao documento onde os dados serão armazenados.
Além disso, continuaremos a usar a programação assíncrona para as operações com serviços externos ao app, garantindo que as interações com o Firebase sejam tratadas de forma eficiente e sem interrupções na interface.
Como funciona o Realtime Database do Firebase?
Antes de continuar primeiramente devemos entender como funciona a estrutura do banco de dados NoSQL no Firebase. Para tanto, é preciso entender que não existem tabelas em um sistema NoSQL e sim documentos. Por causa disso, é possível rapidamente iniciar o desenvolvimento de um aplicativo, pois não é necessário a construção de todo um esquema de banco de dados e seus relacionamentos. O Firebase oferece liberdade ao desenvolvedor como salvar os dados, ficando a cargo da programação como organizar as informações.
No Firebase cada documento é um caminho e neste caminho podem ser salvos dados ou listas. É necessário obter uma referência ao nome do caminho para se ter acesso aos dados e a seguir realizar as operações adequadas seja o dado uma lista ou um objeto.
Abaixo, o código completo do fragmento de Cadastro e na sequência as explicações sobre cada método:
package ...
import ...
class CadastroFragment : Fragment() {
//binding das views automatizado
private var _binding: FragmentCadastroBinding? = null
private val binding get() = _binding!!
//firebase
private lateinit var mAuth: FirebaseAuth //acessa os recursos de autenticação do Firebase
private lateinit var mDatabase: FirebaseDatabase
private lateinit var mUsuarioRef: DatabaseReference
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentCadastroBinding.inflate(inflater, container, false)
binding.cadastrarButton.setOnClickListener {
cadastrarUsuario();
}
//inicializa firebase
mAuth = Firebase.auth
mDatabase = Firebase.database
mUsuarioRef = mDatabase.getReference("usuarios")
// Inflate the layout for this fragment
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
fun cadastrarUsuario(){
//leitura dos dados inseridos na UI
val nome = binding.nomeTextInputLayout.editText?.text.toString()
val telefone = binding.telefoneTextInputLayout.editText?.text.toString()
val email = binding.emailTextInputLayout.editText?.text.toString()
val senha = binding.senhaTextInputLayout.editText?.text.toString()
Log.d("TODO2024", "Tentando criar usuario auth")
//cria um novo login firebase
mAuth.createUserWithEmailAndPassword(email, senha)
.addOnCompleteListener { task: Task<AuthResult> ->
if (!task.isSuccessful) {
Log.w("TODO2024", "Falha ao criar novo Login: ", task.exception)
} else {
Log.d("TODO2024", "Login criado com sucesso")
//Le o UUI do novo usuário criado
val uui = task.result.user!!.uid
//E cria um novo usuario
val usuario: Usuario = Usuario(nome, telefone, email)
criarUsuario(uui, usuario)
}
}
}
private fun criarUsuario(uui: String, usuario: Usuario) {
mUsuarioRef.child(uui).setValue(usuario)
.addOnCompleteListener { task ->
if (!task.isSuccessful) {
Log.w(
"TODO2024",
"Falha ao criar dados do usuario: ",
task.exception
)
} else {
Log.d("TODO2024", "Usuario criado com sucesso")
goToHome()
}
}
}
private fun goToHome() {
findNavController(requireView()).navigate(R.id.action_cadastroFragment_to_homeFragment)
}
}
Método onCreateView
No método onCreateView, configuramos o View Binding logo na primeira linha. Após o carregamento do arquivo FragmentCadastroBinding, o objeto binding passa a conter todas as referências aos componentes da interface definidos no layout XML, o que facilita a leitura e manipulação dos dados do formulário. O método então retorna o componente raiz da interface para compor a visualização do fragmento. Com binding, acessamos o botão de cadastro e associamos a ele um evento que chamará a função cadastrarUsuario ao ser pressionado.
Também inicializamos os objetos necessários para as operações com o Firebase. O objeto mAuth lida com os serviços de autenticação do app, enquanto mDatabase se conecta ao Realtime Database do projeto. Lembre-se de que o arquivo de configuração google-services.json centraliza as informações para essa conexão, o qual foi adicionado usando o Firebase Assistant do Android Studio — caso ainda não tenha feito essa configuração, é importante revisar os passos anteriores.
Para acessar os dados no Realtime Database a partir de mDatabase, criamos um objeto do tipo DatabaseReference. Essa referência possibilita a leitura e gravação de dados no caminho especificado no banco. Neste caso, queremos acesso ao documento "usuarios", então utilizamos getReference("usuarios"). Para acessar outros documentos, basta ajustar o nome do caminho de referência conforme necessário.
Método cadastrarUsuario
Vamos adicionar um novo usuário ao sistema através do serviço de autenticação do Firebase utilizando e-mail e senha com o método createUserWithEmailAndPassword do objeto mAuth. Esse método faz uma requisição à API do Firebase, e a resposta não é imediata; por isso, precisamos usar programação assíncrona para não bloquear a interface do usuário durante a autenticação.
Novamente precisamos lidar com a programação assíncrona. Vamos implementar um método para lidar com a resposta do evento addOnCompleteListener. Esse evento recebe um objeto task que contém o resultado da autenticação (AuthResult). Com ele, verificamos se a operação foi bem-sucedida usando um fluxo de decisão, que nos permite escolher a ação adequada para cada situação.
- Em caso de sucesso: login criado com sucesso mas também queremos salvar as informações pessoais do usuário no documento usuarios. Assim, criamos um objeto da classe Usuário com as informações do formulário e chamamos uma função criarUsuario encaminhando o objeto usuário criado e o código UUID. Onde UUID (Universally Unique Identifier) é um identificador único que permite diferenciar cada registro ou usuário no banco de dados.
- Em caso de falha: registramos uma mensagem de log com o erro. Essas mensagens podem ser visualizadas no LogCat do Android Studio, uma ferramenta útil para diagnosticar problemas. Se o Firebase estiver mal configurado, a conexão de rede apresentar problemas ou houver algum outro erro, o log exibirá informações úteis para corrigir a questão.
Método criarUsuario
Vamos armazenar as informações pessoais do usuário em um documento do Firebase, salvando-o em uma chave cujo valor é o UUID do usuário. Em bancos de dados NoSQL, como o Firebase, não existe uma "chave primária" no modelo tradicional de bancos relacionais, mas o uso de um UUID exclusivo para cada usuário nos permite criar uma estrutura similar. Assim, as informações do usuário serão salvas no caminho "usuarios/uuid", onde cada uuid representa um usuário único no sistema.
Dessa forma, ao salvar diversos usuários na coleção "usuarios", o caminho ficará organizado por UUIDs, e cada documento corresponderá a um usuário específico. Isso facilita futuras consultas e operações de leitura, pois, para obter as informações de um usuário específico, basta acessar diretamente o caminho "usuarios/uuid", onde uuid é obtido a partir do serviço de autenticação do Firebase. Essa estrutura torna as buscas e atualizações mais eficientes, além de manter o banco de dados organizado e escalável.
A primeira linha de código do método criarUsuario pode ser explicada em partes: primeiro, mUsuarioRef referencia o caminho principal "usuarios", enquanto o método child acessa um subcaminho específico — neste caso, o UUID do usuário. Se o subcaminho não existir, ele é automaticamente criado. Em seguida, o método setValue é responsável por salvar o objeto no banco de dados Firebase, convertendo-o para o formato JSON antes de armazená-lo.
Como Usuario é uma data class do Kotlin, seus dados são corretamente convertidos para JSON. Além de objetos complexos, setValue também permite o salvamento de dados simples, como Boolean, Long, Double, String, Map<String, Object> e List<Object>.
Novamente precisamos lidar com programação assíncrona. Em caso de sucesso usamos o método goToHome para a navegação voltar a tela inicial do aplicativo.
9. Considerações Finais
Neste livro, você desenvolveu a primeira parte do aplicativo Lista de Tarefas, discutindo as funcionalidades principais e a integração com os serviços do Firebase.
Exploramos a arquitetura de um aplicativo Android mais complexo, utilizando uma toolbar, navegação e fragmentos para organizar as telas. Com a "Basic Views Activity" como ponto de partida, você entendeu como essa template preconfigura uma base sólida, com fragmentos e navegação integrados para facilitar o desenvolvimento.
A interface gráfica (GUI) foi construída com diferentes tipos de layout, e você aprendeu a utilizar componentes como o TextInputLayout, personalizando formulários por meio das propriedades `imeOptions` e `inputType` para otimizar a entrada de dados.
No Firebase, configuramos os serviços de autenticação e banco de dados em tempo real (Realtime Database), além de implementar um sistema de usuários com telas de login, cadastro e página inicial.
Na segunda parte do projeto, vamos expandir o aplicativo para incluir funcionalidades da lista de tarefas, exibindo na tela inicial uma lista com as tarefas, um campo de entrada para adicionar novas, além de botões para excluir e checkboxes para marcar tarefas concluídas.
10. Referências
Paul Deitel, Harvey Deitel, Abbey Deitel, Michael Morgano. ANDROID para programadores: uma abordagem baseada em aplicativos. Revisão de Daniel Antonio Callegari; Tradução de João Eduardo Nobrega Tortello. Porto Alegre: Bookman, 2012.
LECHETA, Ricardo R. Android essencial com Kotlin. São Paulo: Novatec, 2019.
Documentação do Firebase para Android Development. Android Developers, Google. Disponível em: https://firebase.google.com/docs/android/setup. Acesso em: 22 out. 2024.
11. Ficha Técnica
| VERSÃO ATUAL - 2024.2 | |
|---|---|
| Autoria | Bruno Crestani Calegaro |
| Design Instrucional | Bruno Crestani Calegaro |
| Design Multimídia | Bruno Crestani Calegaro |
| Revisão textual e normativa |
Bruno Crestani Calegaro |

Este trabalho está licenciado com uma Licença Creative Commons - Atribuição-NãoComercial-CompartilhaIgual 4.0 Internacional.