Tutorial do Android Firebase Realtime Database com RecyclerView
Nesta parte, queremos ver vários exemplos de banco de dados RecyclerView e Firebase Realtime. Basicamente como realizar várias operações CRUD como adicionar, recuperar e mostrar no recyclerview.
O que é o Firebase Realtime Database?
O Firebase Realtime Database é um dos serviços fornecidos pelo Firebase Platform, de propriedade do Google.
Basicamente é o que chamamos de Database BAAS, ou Database Backend As A Service. Está hospedado na Nuvem.
Por que o Firebase Realtime Database?
Ele difere de muitos bancos de dados que você já deve conhecer de várias maneiras. Essas formas são o que dá as vantagens do Firebase Realtime Database.
- Está hospedado na Nuvem enquanto outros como SQLite e Realm estão hospedados localmente. Isso torna o Firebase Realtime Database acessível a muitos aplicativos. Bancos de dados como SQLite e Realm são localizados em um único aplicativo. O Firebase Realtime Database é acessível a muitos aplicativos.
- É em tempo real. Esta é a maior diferença. Isso significa que você economiza dados e automaticamente os dados em todos os aplicativos conectados são atualizados instantaneamente. Isso o torna bastante aplicável a muitos tipos de aplicativos, como aplicativos de bate-papo e mensagens, aplicativos que exigem sincronização instantânea.
- Armazena dados em formato json ao contrário de tabelas em sqlite. Isso torna o Firebase Realtime Database bastante escalável.
- Tem planos gratuitos e pagos. Este é o melhor cenário, pois você pode usá-lo para fins comerciais e de aprendizado.
O que é RecyclerView
RecyclerView é um adaptador para Android que nos permite renderizar grandes conjuntos de dados com eficiência. Normalmente para renderizar dados de listas no android você precisa de um adapterview e um adapter. O adapterview é o widget de lista e os exemplos incluem ListView, Gridview, Spinner e, claro, RecyclerView.
Em seguida, o adaptador é normalmente responsável por conectar o adapterview à fonte de dados. E, de fato, você normalmente pode usar layouts personalizados para apresentar um único item de lista. Esse layout também é inflado dentro do adaptador.
Leia mais sobre o RecyclerView aqui.
Por que RecyclerView?
Bem, dissemos que várias visualizações de adaptadores podem ser usadas para apresentação de dados no Android. Há ListView, GridView, Spinner etc. ListView costumava ser o mais popular até a introdução do RecyclerView.
Atualmente, o recyclerview é o adapterview mais usado devido à sua flexibilidade e desempenho. O RecyclerView pode ser usado para construir quase qualquer tipo de visualização, desde uma visualização de lista, até uma visualização de grade/escalonada, uma visualização de tabela, um calendário etc.
Este fato o torna bastante especial e utilizável em muitos cenários. Mesmo assim, não é muito mais difícil do que as outras visualizações de adaptadores.
Ferramentas usadas
Este exemplo foi escrito com as seguintes ferramentas:
- Microsoft Windows 8.1 - Este é o meu sistema operacional.
- Android Studio - Este é o meu IDE (Kit de Desenvolvimento Integrado) da Jetbrains e Google.
- Emulador Genymotion - Usamos para testar nossos aplicativos.
- Linguagem : Java - Java é a linguagem de programação mais popular.
1. Android Firebase => Simple RecyclerView - Salvar, Recuperar e Mostrar
[center]Android Firebase Realtime Database recyclerVisualizar Tutorial[/center]
Este é um tutorial do Firebase RecyclerView para Android. Como salvar dados no Firebase, recupere e mostre esses dados em um Recyclerview simples. Usamos apenas um único campo de dados.
Conceitos gerais que você aprende com este exemplo.
Aqui estão alguns dos conceitos que você pode aprender com este tutorial:
- O que é Firebase e o que é RecyclerView e por que usá-los.
- Como salvar dados de edittext para o google Firebase Realtime Database.
- Como obter ou recuperar ou ler dados do Firebase Database anexando eventos a uma instância
DatabaseReference
e, em seguida, preenchendo uma lista de matrizes java - Como vincular os dados recuperados a uma instância da subclasse
RecyclerView.Adapter
. - Como criar e operar em banco de dados no Firebase.
- Aplicativos de exemplo do Firebase com recyclerview.
- Sincronização de banco de dados Firebase
Conceitos específicos que você aprenderá
- Como usar o Firebase Database Reference.
- Como adicionar filho à referência do banco de dados do Firebase
Demonstração
Aqui está a demonstração do projeto para este tutorial:
Instalação e configuração
(uma). Criar Projeto de Atividade Básica
- Primeiro crie um novo projeto no android studio.
(b). Criar Firebase e baixar arquivo de configuração
Vá até o Firebase Console, crie um aplicativo Firebase, registre o ID do seu aplicativo e baixe o arquivo google-services.json
. Adicione-o à pasta do seu aplicativo.
(c). Especificar URL do repositório Maven
Vá para o nível do projeto (pasta do projeto) build.gradle
e
- Adicione o caminho de classe dos serviços do Google conforme abaixo
- Adicione o URL do repositório maven
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.google.gms:google-services:3.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
maven {
url "https://maven.google.com" // Google's Maven repository
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Isso nos permitirá buscar nosso Firebase em maven.google com
. O Firebase é uma biblioteca de terceiros e precisa ser baixado para que possamos usá-lo em nosso projeto.
(d). Adicionar dependências do Firebase
Adicione-os no nível do aplicativo (pasta do aplicativo) build.gradle, precisamos adicionar várias dependências. Adicionamos bibliotecas de suporte como appcompat
, design
e cardview
. AppCompat nos dará AppCompatActivity, a classe da qual nosso MainActivity
será derivado. Nós os adicionamos usando a instrução implementation
.
O suporte design
nos dará o recyclerveiew que é nosso widget de lista. É o que vamos preencher com os dados que consultamos no nosso Firebase. O cardview
, por outro lado, nos permitirá trabalhar com cardviews como nossas visualizações de itens. A visualização do reciclador deve incluir visualizações de cartão.
Em seguida, adicionamos o Firebase Core e o Firebase Database. O Firebase Remember é uma plataforma, enquanto o Firebase Database é o banco de dados em que armazenamos nossos dados. Você pode usar versões posteriores. No entanto, não se esqueça de aplicar os serviços do google como fizemos.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
implementation 'com.android.support:appcompat-v7:23.3.0'
implementation 'com.android.support:design:23.3.0'
implementation 'com.android.support:cardview-v7:23.3.0'
implementation 'com.google.firebase:firebase-core:11.8.0'
implementation 'com.google.firebase:firebase-database:11.8.0'
}
apply plugin: 'com.google.gms.google-services'
Certifique-se de apply plugin: 'com.google.gms.google-services'
como acima.
2. Nosso código Java
Escrevemos este exemplo usando a linguagem de programação Java. Então, vamos desacoplar várias partes do nosso aplicativo em várias classes.
(uma). Nossa classe modelo
- É nossa classe Data Object
- Deve ter um construtor vazio.
- Você pode criar, passar dados e usar outros construtores
Como modelo ou classe de objeto de dados representa basicamente uma classe que irá modelar nossos dados. Quando você está trabalhando com qualquer forma de dados, é sempre uma boa ideia representar os dados em uma classe simples concreta. O objeto dessa classe pode então ser consultado conforme necessário. Normalmente, esses tipos de classes têm o que chamamos de métodos de acesso. Esses métodos são sempre públicos, fornecendo uma maneira de expor as propriedades da classe, que são sempre privadas.
No nosso caso, criamos uma classe chamada Spacecraft
. Essa classe terá uma única propriedade, apenas um nome para guardar o nome daquela espaçonave. Em seguida, fornecemos à nossa classe um construtor padrão público. Esse é um recurso normalmente necessário para mecanismos de banco de dados que dependem da leitura do objeto de dados para gerar automaticamente o esquema do banco de dados. O Firebase Database definitivamente faz isso assim como o Realm, um banco de dados local para java e android.
Em seguida, fornecemos à nossa classe os métodos de acesso getName
e setName
.
package com.tutorials.hp.firebasesimplerecyclerview.m_Model;
public class Spacecraft {
String name;
//EMPTY CONSTR
public Spacecraft() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
(b). Nossa classe FirebaseHelper
- Basicamente, nossa classe CRUD.
- Aqui realizamos leituras e gravações no banco de dados Firebase.
- Para persistir os dados usamos setValue().
- Antes de chamar o método setValue(), chamamos push() para garantir que anexamos dados ao banco de dados, não substituimos.
- Preenchemos um arraylist simples.
Criamos esta classe, a classe FirebaseHelper
para nos permitir salvar, consultar ou ler dados do Firebase. Começamos definindo o pacote para hospedar nossa classe. Em seguida, adicione nossas importações, incluindo várias classes de com.google.firebase.database
.
Definimos vários campos de instância, incluindo:
- DatabaseReference -- Nossa referência de banco de dados.
- Valor booleano - para determinar se salvamos com sucesso ou não.
- ArrayList - Para manter nossos dados obtidos do Firebase.
Começamos recebendo uma Referência de Banco de Dados por meio do construtor. Em seguida, atribuímos a referência do banco de dados ao campo de instância local que mantivemos.
Salvar dados no FirebaseDatabase
Em seguida, definimos um método para salvar dados no Firebase Database. Esse método receberá um objeto Spacecraft como parâmetro. Dado que estamos recebendo o objeto Spacecraft
do mundo exterior, seria ideal primeiro verificar se ele é nulo.
Para salvar dados no Firebase
db.child("Spacecraft").push().setValue(spacecraft);
Nesse caso, db
é nosso DatabaseReference
. Obtemos seu nó filho através do método child()
. Depois passe o nome da nossa "tabela". Em seguida, usamos o método push()
para enviar dados para o Firebase. No entanto, temos que definir o valor que estamos empurrando. Usamos o método setValue
para definir nosso objeto spacecraft
. E é assim que salvamos dados em nosso banco de dados Firebase. Observe que usamos um bloco try catch para capturar um DatabaseException
.
Recuperando dados do banco de dados Firebase
Receberemos dados do Firebase Realtime Database e preencheremos um ArrayList. Então, mais tarde, ArrayList será usado como fonte de dados para nosso adaptador recyclerview.
Para ler dados do Firebase, precisamos anexar um ChildEventListener
à nossa referência de banco de dados. Isso ouvirá as alterações nos nós de dados. Por exemplo, quando um nó filho é adicionado, modificado, removido ou cancelado, obtemos métodos de retorno de chamada contendo nosso instantâneo de dados. Podemos então ler os dados desses instantâneos de dados.
Então, a partir de cada iteração, você pode invocar o método getValue
do filho do instantâneo de dados para obter o objeto. Ler dados de um objeto DataSnapshot é fácil. Você simplesmente percorre seus filhos:
for (DataSnapshot ds : dataSnapshot.getChildren())
{
String name=ds.getValue(Spacecraft.class).getName();
spacecrafts.add(name);
}
Segue o código completo:
package com.tutorials.hp.firebasesimplerecyclerview.m_FireBase;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseException;
import com.google.firebase.database.DatabaseReference;
import com.tutorials.hp.firebasesimplerecyclerview.m_Model.Spacecraft;
import java.util.ArrayList;
public class FirebaseHelper {
DatabaseReference db;
Boolean saved=null;
ArrayList<String> spacecrafts=new ArrayList<>();
public FirebaseHelper(DatabaseReference db) {
this.db = db;
}
//SAVE
public Boolean save(Spacecraft spacecraft)
{
if(spacecraft==null)
{
saved=false;
}else {
try
{
db.child("Spacecraft").push().setValue(spacecraft);
saved=true;
}catch (DatabaseException e)
{
e.printStackTrace();
saved=false;
}
}
return saved;
}
//READ
public ArrayList<String> retrieve()
{
db.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return spacecrafts;
}
private void fetchData(DataSnapshot dataSnapshot)
{
spacecrafts.clear();
for (DataSnapshot ds : dataSnapshot.getChildren())
{
String name=ds.getValue(Spacecraft.class).getName();
spacecrafts.add(name);
}
}
}
(c). Nossa classe MyViewHolder
- Sim, é nossa classe de visor.
- Mantém vistas para uso pronto para reciclagem
package com.tutorials.hp.firebasesimplerecyclerview.m_UI;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import com.tutorials.hp.firebasesimplerecyclerview.R;
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView nameTxt;
public MyViewHolder(View itemView) {
super(itemView);
nameTxt=(TextView) itemView.findViewById(R.id.nameTxt);
}
}
Esse MyViewHolder
é nossa classe ViewHolder. Estes sempre necessários para a reciclagem de visualizações pelo recyclerview. No entanto, para transformar uma classe em um viewholder recyclerview, temos que derivar da classe Recyclerview.ViewHolder
como você viu acima. Começamos improvisando várias classes incluindo o próprio RecyclerView
.
Em nossa classe, mantivemos um TextView chamado nameTxt
. Então nosso construtor MyViewHolder
pegou um objeto View. Esse objeto View foi então passado para a superclasse que é a Recyclerview.ViewHolder
.
Em seguida, referenciamos o nameTxt
de sua especificação de layout.
9. Nossa classe MyAdapter
- Responsável pela Inflação de Layout.
- Também para vinculação de dados a visualizações.
package com.tutorials.hp.firebasesimplerecyclerview.m_UI;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.tutorials.hp.firebasesimplerecyclerview.R;
import java.util.ArrayList;
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
Context c;
ArrayList<String> spacecrafts;
public MyAdapter(Context c, ArrayList<String> spacecrafts) {
this.c = c;
this.spacecrafts = spacecrafts;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v=LayoutInflater.from(c).inflate(R.layout.model,parent,false);
return new MyViewHolder(v);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.nameTxt.setText(spacecrafts.get(position));
}
@Override
public int getItemCount() {
return spacecrafts.size();
}
}
Os adaptadores são importantes na maneira como o Android funciona com a coleta de dados. Dispositivos móveis sejam HTC, Samsung, F7, Apple iOS, Infinix etc, todos eles aplicativos que precisam renderizar listas de dados. Isso é apenas pela natureza dos dispositivos móveis. A tela é sempre pequena e, portanto, é apropriado exibir itens que podem ser rolados.
E o RecyclerView é o adaptador número um para exibir grandes conjuntos de dados. Esses conjuntos de dados podem vir da nuvem, como o Firebase. E, de fato, nossos dados neste caso são provenientes do banco de dados Firebase Realtime. Portanto, preenchemos um ArrayList até agora com os dados que já coletamos. Agora é hora de vincular esses dados. No entanto, isso precisa de um adaptador.
Adaptadores:
- Permita-nos vincular dados às nossas visualizações de adaptador.
- Ajude-nos a inflar layouts personalizados em visualizações para que possamos projetar visualizações personalizadas de adaptadores.
Você cria um adaptador recyclerview derivando de RecyclerView.Adapter<MyViewHolder>
. O parâmetro genérico é o ViewHolder. Derivando dessa classe nos forçará a substituir três métodos:
getItemCount
- Para retornar o número de itens a serem renderizados no recyclerview.onCreateViewHolder
- É aqui que ocorre a inflação. UsamosLayoutInflater para a inflação.onBindViewHolder
- É aqui que ligamos os dados aos widgets que definimos na classe ViewHolder.
Enquanto isso, nosso construtor pegou um objeto Context, bem como o arraylist de nossos dados.
(d). Nossa principal atividade
- Atividade do lançador.
- Referencie RecyclerView e defina seu layoutManager, bem como seu adaptador.
- Mostra a caixa de diálogo de entrada ao clicar no botão FAB.
- Configura nosso Firebase inicializando o DatabaseReference.
package com.tutorials.hp.firebasesimplerecyclerview;
import android.app.Dialog;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.tutorials.hp.firebasesimplerecyclerview.m_FireBase.FirebaseHelper;
import com.tutorials.hp.firebasesimplerecyclerview.m_Model.Spacecraft;
import com.tutorials.hp.firebasesimplerecyclerview.m_UI.MyAdapter;
public class MainActivity extends AppCompatActivity {
DatabaseReference db;
FirebaseHelper helper;
RecyclerView rv;
EditText nameEditTxt;
MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//SETUP RV
rv= (RecyclerView) findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(this));
//SETUP FB
db=FirebaseDatabase.getInstance().getReference();
helper=new FirebaseHelper(db);
//ADAPTER
adapter=new MyAdapter(this,helper.retrieve());
rv.setAdapter(adapter);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
displayInputDialog();
}
});
}
private void displayInputDialog()
{
Dialog d=new Dialog(this);
d.setTitle("Save To Firebase");
d.setContentView(R.layout.input_dialog);
nameEditTxt= (EditText) d.findViewById(R.id.nameEditText);
Button saveBtn= (Button) d.findViewById(R.id.saveBtn);
//SAVE
saveBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//GET DATA
String name=nameEditTxt.getText().toString();
//SET DATA
Spacecraft s=new Spacecraft();
s.setName(name);
//VALIDATE
if(name.length()>0 && name != null)
{
if(helper.save(s))
{
nameEditTxt.setText("");
adapter=new MyAdapter(MainActivity.this,helper.retrieve());
rv.setAdapter(adapter);
}
}else
{
Toast.makeText(MainActivity.this, "Name Cannot Be Empty", Toast.LENGTH_SHORT).show();
}
}
});
d.show();
}
}
11. Nossos layouts
(uma). atividade_main.xml
Este é o nosso layout principal de atividade.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_fitsSystemWindows="true"
tools_context="com.tutorials.hp.firebasesimplerecyclerview.MainActivity">
<android.support.design.widget.AppBarLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android_id="@+id/toolbar"
android_layout_width="match_parent"
android_layout_height="?attr/actionBarSize"
android_background="?attr/colorPrimary"
app_popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton
android_id="@+id/fab"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_gravity="bottom|end"
android_layout_margin="@dimen/fab_margin"
android_src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
(b). content_main.xml
É aqui que adicionamos nosso adapterview, neste caso um recyclerview.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_paddingBottom="@dimen/activity_vertical_margin"
android_paddingLeft="@dimen/activity_horizontal_margin"
android_paddingRight="@dimen/activity_horizontal_margin"
android_paddingTop="@dimen/activity_vertical_margin"
app_layout_behavior="@string/appbar_scrolling_view_behavior"
tools_context="com.tutorials.hp.firebasesimplerecyclerview.MainActivity"
tools_showIn="@layout/activity_main">
<android.support.v7.widget.RecyclerView
android_id="@+id/rv"
android_layout_width="match_parent"
android_layout_height="wrap_content"
/>
</RelativeLayout>
(c). input_dialog.xml
- define nosso layout de diálogos de entrada
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android_orientation="vertical" android_layout_width="match_parent"
android_layout_height="match_parent">
<LinearLayout
android_layout_width="fill_parent"
android_layout_height="match_parent"
android_layout_marginTop="?attr/actionBarSize"
android_orientation="vertical"
android_paddingLeft="15dp"
android_paddingRight="15dp"
android_paddingTop="10dp">
<android.support.design.widget.TextInputLayout
android_id="@+id/nameLayout"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<EditText
android_id="@+id/nameEditText"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_singleLine="true"
android_hint= "Name" />
</android.support.design.widget.TextInputLayout>
<Button android_id="@+id/saveBtn"
android_layout_width="fill_parent"
android_layout_height="wrap_content"
android_text="Save"
android_clickable="true"
android_background="@color/colorAccent"
android_layout_marginTop="10dp"
android_textColor="@android:color/white"/>
</LinearLayout>
</LinearLayout>
(d). model.xml
Este é o nosso modelo de linha RecyclerView. Este layout será inflado na classe do adaptador.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
android_orientation="horizontal" android_layout_width="match_parent"
android_layout_margin="10dp"
card_view_cardCornerRadius="5dp"
card_view_cardElevation="5dp"
android_layout_height="200dp">
<LinearLayout
android_orientation="vertical"
android_layout_width="match_parent"
android_layout_height="match_parent">
<TextView
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceLarge"
android_text="Name"
android_id="@+id/nameTxt"
android_padding="10dp"
android_textColor="@color/colorAccent"
android_textStyle="bold"
android_layout_alignParentLeft="true"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
12. AndroidManifest.xml
- Lembre-se de adicionar permissão para internet em seu arquivo de manifesto.
<uses-permission android_name="android.permission.INTERNET"/>
Download
2. Android Firebase - RecyclerView Multiple Fields
Tutorial do RecyclerView do banco de dados do Firebase Android Este é um tutorial do RecyclerView do banco de dados do Firebase do Android. Como salvar dados no Firebase, recupere e mostre esses dados em um RecyclerView personalizado.
Desta vez, usamos vários campos em vez de um único campo, como fizemos no exemplo anterior.
1. Configurando
(uma). Criar Projeto de Atividade Básica
- Primeiro crie um novo projeto no android studio. Vá para Arquivo --> Novo Projeto.
(b).Crie o Firebase e baixe o arquivo de configuração
Vá até o Firebase Console, crie um aplicativo Firebase, registre o ID do seu aplicativo e baixe o arquivo google-services.json
. Adicione-o à pasta do seu aplicativo.
(c). Especificar URL do repositório Maven
Vá para o nível do projeto (pasta do projeto) build.gradle
e
- Adicione o caminho de classe dos serviços do Google conforme abaixo
- Adicione o URL do repositório maven
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.google.gms:google-services:3.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
maven {
url "https://maven.google.com" // Google's Maven repository
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
(d). Adicionar dependências do Firebase
Adicione-os no nível do aplicativo (pasta do aplicativo) build.gradle
e, em seguida,
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:design:23.3.0'
compile 'com.android.support:cardview-v7:23.3.0'
compile 'com.google.firebase:firebase-core:11.8.0'
compile 'com.google.firebase:firebase-database:11.8.0'
}
apply plugin: 'com.google.gms.google-services'
Certifique-se de apply plugin: 'com.google.gms.google-services'
como acima.
(e). Manifesto Android
- Lembre-se de adicionar permissão para internet em seu arquivo de manifesto.
<?xml version="1.0" encoding="utf-8"?>
<manifest
package="com.tutorials.hp.firebaserecyclermulti_items">
<uses-permission android_name="android.permission.INTERNET"/>
....
</manifest>
2. Aulas
(uma). Nossa classe modelo
- É nossa classe Data Object
- Deve ter um construtor vazio.
- Você pode criar, passar dados e usar outros construtores
package com.tutorials.hp.firebaserecyclermulti_items.m_Model;
/*
* 1. OUR MODEL CLASS
*/
public class Spacecraft {
String name,propellant,description;
public Spacecraft() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPropellant() {
return propellant;
}
public void setPropellant(String propellant) {
this.propellant = propellant;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
(b). Nossa classe FirebaseHelper
- Basicamente, nossa classe CRUD.
- Aqui realizamos leituras e gravações no banco de dados Firebase.
- Para persistir os dados usamos setValue().
- Antes de chamar o método setValue(), chamamos push() para garantir que anexamos dados ao banco de dados, não substituimos.
- Preenchemos um arraylist com objetos de modelo.
package com.tutorials.hp.firebaserecyclermulti_items.m_FireBase;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseException;
import com.google.firebase.database.DatabaseReference;
import com.tutorials.hp.firebaserecyclermulti_items.m_Model.Spacecraft;
import java.util.ArrayList;
/*
* 1. RECEIVE DB REFERENCE
* 2. SAVE
* 3. RETRIEVE
* 4. RETURN ARRAYLIST
*/
public class FirebaseHelper {
DatabaseReference db;
Boolean saved=null;
ArrayList<Spacecraft> spacecrafts=new ArrayList<>();
/*
PASS DATABASE REFRENCE
*/
public FirebaseHelper(DatabaseReference db) {
this.db = db;
}
//WRITE IF NOT NULL
public Boolean save(Spacecraft spacecraft)
{
if(spacecraft==null)
{
saved=false;
}else
{
try
{
db.child("Spacecraft").push().setValue(spacecraft);
saved=true;
}catch (DatabaseException e)
{
e.printStackTrace();
saved=false;
}
}
return saved;
}
//IMPLEMENT FETCH DATA AND FILL ARRAYLIST
private void fetchData(DataSnapshot dataSnapshot)
{
spacecrafts.clear();
for (DataSnapshot ds : dataSnapshot.getChildren())
{
Spacecraft spacecraft=ds.getValue(Spacecraft.class);
spacecrafts.add(spacecraft);
}
}
//READ BY HOOKING ONTO DATABASE OPERATION CALLBACKS
public ArrayList<Spacecraft> retrieve()
{
db.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return spacecrafts;
}
}
(c). Nossa classe ViewHolder
- Mantém as visualizações para nós reciclarmos.
- Subclasses RecyclerView.ViewHolder
package com.tutorials.hp.firebaserecyclermulti_items.m_UI;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import com.tutorials.hp.firebaserecyclermulti_items.R;
/*
* 1. HOLD VIEWS
*/
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView nameTxt,propTxt,descTxt;
public MyViewHolder(View itemView) {
super(itemView);
nameTxt=(TextView) itemView.findViewById(R.id.nameTxt);
propTxt=(TextView) itemView.findViewById(R.id.propellantTxt);
descTxt=(TextView) itemView.findViewById(R.id.descTxt);
}
}
9. Nossa classe MyAdapter
- Responsável pela Inflação de Layout.
- Também para vinculação de dados a visualizações.
- Esta classe subclasses RecyclerView.Adapter
package com.tutorials.hp.firebaserecyclermulti_items.m_UI;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.tutorials.hp.firebaserecyclermulti_items.R;
import com.tutorials.hp.firebaserecyclermulti_items.m_Model.Spacecraft;
import java.util.ArrayList;
/
* 1. LAYOUT INFLATION
* 2. RECEIVE SPACECRAFTS
* 3. PERFORM BINDING
*/
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
Context c;
ArrayList<Spacecraft> spacecrafts;
public MyAdapter(Context c, ArrayList<Spacecraft> spacecrafts) {
this.c = c;
this.spacecrafts = spacecrafts;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v=LayoutInflater.from(c).inflate(R.layout.model,parent,false);
return new MyViewHolder(v);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.nameTxt.setText(spacecrafts.get(position).getName());
holder.propTxt.setText(spacecrafts.get(position).getPropellant());
holder.descTxt.setText(spacecrafts.get(position).getDescription());
}
@Override
public int getItemCount() {
return spacecrafts.size();
}
}
(d). Nossa principal atividade
- Atividade do lançador.
- Referencie RecyclerView e defina seu LayoutManager
- Configure seu adaptador.
- Mostra a caixa de diálogo de entrada ao clicar no botão FAB.
- Configura nosso Firebase inicializando o DatabaseReference.
package com.tutorials.hp.firebaserecyclermulti_items;
import android.app.Dialog;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.tutorials.hp.firebaserecyclermulti_items.m_FireBase.FirebaseHelper;
import com.tutorials.hp.firebaserecyclermulti_items.m_Model.Spacecraft;
import com.tutorials.hp.firebaserecyclermulti_items.m_UI.MyAdapter;
/*
1.INITIALIZE FIREBASE DB
2.INITIALIZE UI
3.DATA*/
public class MainActivity extends AppCompatActivity {
DatabaseReference db;
FirebaseHelper helper;
MyAdapter adapter;
RecyclerView rv;
EditText nameEditTxt,propTxt,descTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//INITIALIZE RV
rv= (RecyclerView) findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(this));
//INITIALIZE FB
db= FirebaseDatabase.getInstance().getReference();
helper=new FirebaseHelper(db);
//ADAPTER
adapter=new MyAdapter(this,helper.retrieve());
rv.setAdapter(adapter);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
displayInputDialog();
}
});
}
//DISPLAY INPUT DIALOG
private void displayInputDialog()
{
//CREATE DIALOG
Dialog d=new Dialog(this);
d.setTitle("Save To Firebase");
d.setContentView(R.layout.input_dialog);
nameEditTxt= (EditText) d.findViewById(R.id.nameEditText);
propTxt= (EditText) d.findViewById(R.id.propellantEditText);
descTxt= (EditText) d.findViewById(R.id.descEditText);
Button saveBtn= (Button) d.findViewById(R.id.saveBtn);
//SAVE
saveBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//GET DATA
String name=nameEditTxt.getText().toString();
String propellant=propTxt.getText().toString();
String desc=descTxt.getText().toString();
//SET DATA
Spacecraft s=new Spacecraft();
s.setName(name);
s.setPropellant(propellant);
s.setDescription(desc);
//SAVE
if(name != null && name.length()>0)
{
if(helper.save(s))
{
nameEditTxt.setText("");
propTxt.setText("");
descTxt.setText("");
adapter=new MyAdapter(MainActivity.this,helper.retrieve());
rv.setAdapter(adapter);
}
}else
{
Toast.makeText(MainActivity.this, "Name Must Not Be Empty", Toast.LENGTH_SHORT).show();
}
}
});
d.show();
}
}
3. Nossos layouts
(uma). InputDialog.xml
- define nosso layout de diálogos de entrada
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android_orientation="vertical" android_layout_width="match_parent"
android_layout_height="match_parent">
<LinearLayout
android_layout_width="fill_parent"
android_layout_height="match_parent"
android_layout_marginTop="?attr/actionBarSize"
android_orientation="vertical"
android_paddingLeft="15dp"
android_paddingRight="15dp"
android_paddingTop="50dp">
<android.support.design.widget.TextInputLayout
android_id="@+id/nameLayout"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<EditText
android_id="@+id/nameEditText"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_singleLine="true"
android_hint= "Name" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android_id="@+id/propLayout"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<EditText
android_id="@+id/propellantEditText"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_singleLine="true"
android_hint= "Propellant" />
<android.support.design.widget.TextInputLayout
android_id="@+id/descLayout"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<EditText
android_id="@+id/descEditText"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_singleLine="true"
android_hint= "Description" />
</android.support.design.widget.TextInputLayout>
</android.support.design.widget.TextInputLayout>
<Button android_id="@+id/saveBtn"
android_layout_width="fill_parent"
android_layout_height="wrap_content"
android_text="Save"
android_clickable="true"
android_background="@color/colorAccent"
android_layout_marginTop="40dp"
android_textColor="@android:color/white"/>
</LinearLayout>
</LinearLayout>
(b). Model.xml
- Como cada item de visualização deve aparecer.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
android_orientation="horizontal" android_layout_width="match_parent"
android_layout_margin="10dp"
card_view_cardCornerRadius="5dp"
card_view_cardElevation="5dp"
android_layout_height="200dp">
<LinearLayout
android_orientation="vertical"
android_layout_width="match_parent"
android_layout_height="match_parent">
<TextView
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceLarge"
android_text="Name"
android_id="@+id/nameTxt"
android_padding="10dp"
android_textColor="@color/colorAccent"
android_textStyle="bold"
android_layout_alignParentLeft="true"
/>
<TextView
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceLarge"
android_text="Description....................."
android_lines="3"
android_id="@+id/descTxt"
android_padding="10dp"
android_layout_alignParentLeft="true"
/>
<TextView
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceMedium"
android_text="Propellant"
android_textStyle="italic"
android_id="@+id/propellantTxt" />
</LinearLayout>
</android.support.v7.widget.CardView>
4. Download
3. Android Firebase - RecyclerView Master Detail [Open Activity]
Olá, bem-vindo ao nosso tutorial detalhado do Android Firebase RecyclerView Master.
Este é um tutorial do firebase recyclerview para Android. Como salvar dados no Firebase, recupere e mostre esses dados em um gridview personalizado.
- Salve dados do edittext para o banco de dados do google firebase.
- Recupere os dados anexando eventos a uma instância DatabaseReference.
- Vincule os dados a um gridview personalizado usando uma subclasse BaseAdapter.
- Manipular itemClicks do GridView.
- Abra uma nova atividade quando um item da grade for clicado.
- Passar dados para essa nova atividade
O que é o Firebase Realtime Database?
O banco de dados Firebase Realtime é um back-end de banco de dados como uma solução hospedada em nuvem que nos dá a plataforma para criar aplicativos avançados. Normalmente, estamos acostumados a fazer solicitações HTTP para ler ou gravar dados em nossos servidores. Mas não no Firebase. Ele usa tecnologia de sincronização que permite que seja em tempo real, mas ainda com alto desempenho.
Principais recursos?
- É em tempo real.
- Platfrom Independente.
- Fácil Controle de Acesso.
- É uma solução NoSQL e altamente otimizada para desempenho.
- Tem capacidade offline.
- Seu usuário amigável.
Tutorial em vídeo Para obter mais explicações, confira nosso tutorial em vídeo abaixo.
Configuração
(a) .Criar Projeto de Atividade Básica
- Primeiro crie um novo projeto no android studio. Vá para Arquivo --> Novo Projeto.
(b). Criar Firebase e baixar arquivo de configuração
Vá até o Firebase Console, crie um aplicativo Firebase, registre o ID do seu aplicativo e baixe o arquivo google-services.json
. Adicione-o à pasta do seu aplicativo.
(c). Especificar URL do repositório Maven
Vá para o nível do projeto (pasta do projeto) build.gradle
e
- Adicione o caminho de classe dos serviços do Google conforme abaixo
- Adicione o URL do repositório maven
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.google.gms:google-services:3.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
maven {
url "https://maven.google.com" // Google's Maven repository
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
(d). Adicionar dependências do Firebase
Adicione-os no nível do aplicativo (pasta do aplicativo) build.gradle e, em seguida,
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:design:23.3.0'
compile 'com.android.support:cardview-v7:23.3.0'
compile 'com.google.firebase:firebase-core:11.8.0'
compile 'com.google.firebase:firebase-database:11.8.0'
}
apply plugin: 'com.google.gms.google-services'
Certifique-se de apply plugin: 'com.google.gms.google-services'
como acima.
(e). AndroidManifest.xml
- Lembre-se de adicionar permissão para internet em seu arquivo de manifesto.
<?xml version="1.0" encoding="utf-8"?>
<manifest
package="com.tutorials.hp.firebaserecyclermdetail">
<uses-permission android_name="android.permission.INTERNET"/>
<application
android_allowBackup="true"
android_icon="@mipmap/ic_launcher"
android_label="@string/app_name"
android_supportsRtl="true"
android_theme="@style/AppTheme">
<activity
android_name=".MainActivity"
android_label="@string/app_name"
android_theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android_name="android.intent.action.MAIN" />
<category android_name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android_name=".DetailActivity"
android_label="Detail View"
android_theme="@style/AppTheme.NoActionBar">
</activity>
</application>
</manifest>
Classes Java
(uma). Nave espacial.java
- É nossa classe Data Object
- Deve ter um construtor vazio.
- Você pode criar, passar dados e usar outros construtores
package com.tutorials.hp.firebaserecyclermdetail.m_Model;
/*
* 1. OUR MODEL CLASS
*/
public class Spacecraft {
String name,propellant,description;
public Spacecraft() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPropellant() {
return propellant;
}
public void setPropellant(String propellant) {
this.propellant = propellant;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
(b). FirebaseHelper.java
- Basicamente, nossa classe CRUD.
- Aqui realizamos leituras e gravações no banco de dados Firebase.
- Para persistir os dados usamos setValue().
- Antes de chamar o método setValue(), chamamos push() para garantir que anexamos dados ao banco de dados, não substituimos.
- Preenchemos um arraylist com objetos de naves espaciais.
package com.tutorials.hp.firebaserecyclermdetail.m_FireBase;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseException;
import com.google.firebase.database.DatabaseReference;
import com.tutorials.hp.firebaserecyclermdetail.m_Model.Spacecraft;
import java.util.ArrayList;
/*
* 1.SAVE DATA TO FIREBASE
* 2. RETRIEVE
* 3.RETURN AN ARRAYLIST
*/
public class FirebaseHelper {
DatabaseReference db;
Boolean saved=null;
ArrayList<Spacecraft> spacecrafts=new ArrayList<>();
public FirebaseHelper(DatabaseReference db) {
this.db = db;
}
//WRITE IF NOT NULL
public Boolean save(Spacecraft spacecraft)
{
if(spacecraft==null)
{
saved=false;
}else
{
try
{
db.child("Spacecraft").push().setValue(spacecraft);
saved=true;
}catch (DatabaseException e)
{
e.printStackTrace();
saved=false;
}
}
return saved;
}
//IMPLEMENT FETCH DATA AND FILL ARRAYLIST
private void fetchData(DataSnapshot dataSnapshot)
{
spacecrafts.clear();
for (DataSnapshot ds : dataSnapshot.getChildren())
{
Spacecraft spacecraft=ds.getValue(Spacecraft.class);
spacecrafts.add(spacecraft);
}
}
//READ THEN RETURN ARRAYLIST
public ArrayList<Spacecraft> retrieve() {
db.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return spacecrafts;
}
}
(c). MyViewHolder.java
- É a nossa classe de visor
- Mantém as visualizações mostradas em nosso RecyclerView
package com.tutorials.hp.firebaserecyclermdetail.m_UI;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import com.tutorials.hp.firebaserecyclermdetail.R;
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView nameTxt,propTxt,descTxt;
ItemClickListener itemClickListener;
public MyViewHolder(View itemView) {
super(itemView);
nameTxt= (TextView) itemView.findViewById(R.id.nameTxt);
propTxt= (TextView) itemView.findViewById(R.id.propellantTxt);
descTxt= (TextView) itemView.findViewById(R.id.descTxt);
itemView.setOnClickListener(this);
}
public void setItemClickListener(ItemClickListener itemClickListener)
{
this.itemClickListener=itemClickListener;
}
@Override
public void onClick(View view) {
this.itemClickListener.onItemClick(this.getLayoutPosition());
}
}
(d). MyAdapter.java
- Responsável pela Inflação de Layout.
- Também para vinculação de dados a visualizações.
- Em seguida, abre uma nova atividade e passa os dados para ela via android.Content.Intent.
package com.tutorials.hp.firebaserecyclermdetail.m_UI;
import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.tutorials.hp.firebaserecyclermdetail.DetailActivity;
import com.tutorials.hp.firebaserecyclermdetail.R;
import com.tutorials.hp.firebaserecyclermdetail.m_Model.Spacecraft;
import java.util.ArrayList;
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
Context c;
ArrayList<Spacecraft> spacecrafts;
public MyAdapter(Context c, ArrayList<Spacecraft> spacecrafts) {
this.c = c;
this.spacecrafts = spacecrafts;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v=LayoutInflater.from(c).inflate(R.layout.model,parent,false);
return new MyViewHolder(v);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
final Spacecraft s=spacecrafts.get(position);
holder.nameTxt.setText(s.getName());
holder.propTxt.setText(s.getPropellant());
holder.descTxt.setText(s.getDescription());
holder.setItemClickListener(new ItemClickListener() {
@Override
public void onItemClick(int pos) {
//OPEN DETAI ACTIVITY
openDetailActivity(s.getName(),s.getDescription(),s.getPropellant());
}
});
}
@Override
public int getItemCount() {
return spacecrafts.size();
}
//OPEN DETAIL ACTIVITY
private void openDetailActivity(String...details)
{
Intent i=new Intent(c,DetailActivity.class);
i.putExtra("NAME_KEY",details[0]);
i.putExtra("DESC_KEY",details[1]);
i.putExtra("PROP_KEY",details[2]);
c.startActivity(i);
}
}
(e). ItemClickListener.java
- Define para nós a assinatura do nosso método onItemClick().
package com.tutorials.hp.firebaserecyclermdetail.m_UI;
public interface ItemClickListener {
void onItemClick(int pos);
}
12. MainActivity.java
- Atividade do lançador.
- Referência RecyclerView, defina seu adaptador.
- Mostra a caixa de diálogo de entrada ao clicar no botão FAB.
- Configura nosso Firebase inicializando o DatabaseReference.
package com.tutorials.hp.firebaserecyclermdetail;
import android.app.Dialog;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.tutorials.hp.firebaserecyclermdetail.m_FireBase.FirebaseHelper;
import com.tutorials.hp.firebaserecyclermdetail.m_Model.Spacecraft;
import com.tutorials.hp.firebaserecyclermdetail.m_UI.MyAdapter;
/*
1.INITIALIZE FIREBASE DB
2.INITIALIZE UI
3.DATA INPUT
*/
public class MainActivity extends AppCompatActivity {
DatabaseReference db;
FirebaseHelper helper;
MyAdapter adapter;
RecyclerView rv;
EditText nameEditTxt,propTxt,descTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//SETUP RECYCLER
rv = (RecyclerView) findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(this));
//INITIALIZE FIREBASE DB
db= FirebaseDatabase.getInstance().getReference();
helper=new FirebaseHelper(db);
//ADAPTER
adapter=new MyAdapter(this,helper.retrieve());
rv.setAdapter(adapter);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
displayInputDialog();
}
});
}
//DISPLAY INPUT DIALOG
private void displayInputDialog()
{
Dialog d=new Dialog(this);
d.setTitle("Save To Firebase");
d.setContentView(R.layout.input_dialog);
nameEditTxt= (EditText) d.findViewById(R.id.nameEditText);
propTxt= (EditText) d.findViewById(R.id.propellantEditText);
descTxt= (EditText) d.findViewById(R.id.descEditText);
Button saveBtn= (Button) d.findViewById(R.id.saveBtn);
//SAVE
saveBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//GET DATA
String name=nameEditTxt.getText().toString();
String propellant=propTxt.getText().toString();
String desc=descTxt.getText().toString();
//SET DATA
Spacecraft s=new Spacecraft();
s.setName(name);
s.setPropellant(propellant);
s.setDescription(desc);
//SIMPLE VALIDATION
if(name != null && name.length()>0)
{
//THEN SAVE
if(helper.save(s))
{
//IF SAVED CLEAR EDITXT
nameEditTxt.setText("");
propTxt.setText("");
descTxt.setText("");
adapter=new MyAdapter(MainActivity.this,helper.retrieve());
rv.setAdapter(adapter);
}
}else
{
Toast.makeText(MainActivity.this, "Name Must Not Be Empty", Toast.LENGTH_SHORT).show();
}
}
});
d.show();
}
}
(f). DetailActivity.java
- Sim, a atividade de detalhes aqui. Para mostrar nossos detalhes.
- Recebe dados de MainActivity via Intent.
- Mostra os dados em TextViews.
package com.tutorials.hp.firebaserecyclermdetail;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.TextView;
public class DetailActivity extends AppCompatActivity {
TextView nameTxt,descTxt, propTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
nameTxt = (TextView) findViewById(R.id.nameDetailTxt);
descTxt= (TextView) findViewById(R.id.descDetailTxt);
propTxt = (TextView) findViewById(R.id.propellantDetailTxt);
//GET INTENT
Intent i=this.getIntent();
//RECEIVE DATA
String name=i.getExtras().getString("NAME_KEY");
String desc=i.getExtras().getString("DESC_KEY");
String propellant=i.getExtras().getString("PROP_KEY");
//BIND DATA
nameTxt.setText(name);
descTxt.setText(desc);
propTxt.setText(propellant);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
}
Esquemas
(uma). ActivityMain.xml
- Contém nosso ContentMain.xml
- Define nosso ActionButton flutuante.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_fitsSystemWindows="true"
tools_context="com.tutorials.hp.firebaserecyclermdetail.MainActivity">
<android.support.design.widget.AppBarLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android_id="@+id/toolbar"
android_layout_width="match_parent"
android_layout_height="?attr/actionBarSize"
android_background="?attr/colorPrimary"
app_popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton
android_id="@+id/fab"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_gravity="bottom|end"
android_layout_margin="@dimen/fab_margin"
android_src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
(b). ContentMain.xml
- Nossa visão principal
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_paddingBottom="@dimen/activity_vertical_margin"
android_paddingLeft="@dimen/activity_horizontal_margin"
android_paddingRight="@dimen/activity_horizontal_margin"
android_paddingTop="@dimen/activity_vertical_margin"
app_layout_behavior="@string/appbar_scrolling_view_behavior"
tools_context="com.tutorials.hp.firebaserecyclermdetail.MainActivity"
tools_showIn="@layout/activity_main">
<android.support.v7.widget.RecyclerView
android_id="@+id/rv"
android_layout_width="match_parent"
android_layout_height="wrap_content"
/>
</RelativeLayout>
(c). inputdialog.xml
- define nosso layout de diálogos de entrada
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android_orientation="vertical" android_layout_width="match_parent"
android_layout_height="match_parent">
<LinearLayout
android_layout_width="fill_parent"
android_layout_height="match_parent"
android_layout_marginTop="?attr/actionBarSize"
android_orientation="vertical"
android_paddingLeft="15dp"
android_paddingRight="15dp"
android_paddingTop="50dp">
<android.support.design.widget.TextInputLayout
android_id="@+id/nameLayout"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<EditText
android_id="@+id/nameEditText"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_singleLine="true"
android_hint= "Name" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android_id="@+id/propLayout"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<EditText
android_id="@+id/propellantEditText"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_singleLine="true"
android_hint= "Propellant" />
<android.support.design.widget.TextInputLayout
android_id="@+id/descLayout"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<EditText
android_id="@+id/descEditText"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_singleLine="true"
android_hint= "Description" />
</android.support.design.widget.TextInputLayout>
</android.support.design.widget.TextInputLayout>
<Button android_id="@+id/saveBtn"
android_layout_width="fill_parent"
android_layout_height="wrap_content"
android_text="Save"
android_clickable="true"
android_background="@color/colorAccent"
android_layout_marginTop="40dp"
android_textColor="@android:color/white"/>
</LinearLayout>
</LinearLayout>
(d). Model.xml
- define nossos CardViews personalizados.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
android_orientation="horizontal" android_layout_width="match_parent"
android_layout_margin="10dp"
card_view_cardCornerRadius="5dp"
card_view_cardElevation="5dp"
android_layout_height="200dp">
<LinearLayout
android_orientation="vertical"
android_layout_width="match_parent"
android_layout_height="match_parent">
<TextView
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceLarge"
android_text="Name"
android_id="@+id/nameTxt"
android_padding="10dp"
android_textColor="@color/colorAccent"
android_textStyle="bold"
android_layout_alignParentLeft="true"
/>
<TextView
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceLarge"
android_text="Description....................."
android_lines="3"
android_id="@+id/descTxt"
android_padding="10dp"
android_layout_alignParentLeft="true"
/>
<TextView
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceMedium"
android_text="Propellant"
android_textStyle="italic"
android_id="@+id/propellantTxt" />
</LinearLayout>
</android.support.v7.widget.CardView>
(f). atividade_detalhe.xml
- Contém nosso ContentDetail.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_fitsSystemWindows="true"
tools_context="com.tutorials.hp.firebaserecyclermdetail.DetailActivity">
<android.support.design.widget.AppBarLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android_id="@+id/toolbar"
android_layout_width="match_parent"
android_layout_height="?attr/actionBarSize"
android_background="?attr/colorPrimary"
app_popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_detail" />
<android.support.design.widget.FloatingActionButton
android_id="@+id/fab"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_gravity="bottom|end"
android_layout_margin="@dimen/fab_margin"
android_src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
(g). content_detail.xml
- Nossa visão de detalhes.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_paddingBottom="@dimen/activity_vertical_margin"
android_paddingLeft="@dimen/activity_horizontal_margin"
android_paddingRight="@dimen/activity_horizontal_margin"
android_paddingTop="@dimen/activity_vertical_margin"
app_layout_behavior="@string/appbar_scrolling_view_behavior"
tools_context="com.tutorials.hp.firebaserecyclermdetail.DetailActivity"
tools_showIn="@layout/activity_detail">
<android.support.v7.widget.CardView
android_orientation="horizontal" android_layout_width="match_parent"
android_layout_margin="5dp"
card_view_cardCornerRadius="10dp"
card_view_cardElevation="5dp"
android_layout_height="match_parent">
<LinearLayout
android_orientation="vertical"
android_layout_width="match_parent"
android_layout_height="match_parent"
android_weightSum="1">
<LinearLayout
android_orientation="horizontal"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<ImageView
android_id="@+id/articleDetailImg"
android_layout_width="320dp"
android_layout_height="wrap_content"
android_paddingLeft="10dp"
android_layout_alignParentTop="true"
android_scaleType="centerCrop"
android_src="@drawable/spitzer" />
<LinearLayout
android_orientation="vertical"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<TextView
android_id="@+id/nameDetailTxt"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceLarge"
android_padding="5dp"
android_minLines="1"
android_textStyle="bold"
android_textColor="@color/colorAccent"
android_text="Title" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android_layout_width="fill_parent"
android_layout_height="match_parent"
android_layout_marginTop="?attr/actionBarSize"
android_orientation="vertical"
android_paddingLeft="5dp"
android_paddingRight="5dp"
android_paddingTop="5dp">
<TextView
android_id="@+id/propellantDetailTxt"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceLarge"
android_padding="5dp"
android_minLines="1"
android_text="DATE" />
<TextView
android_id="@+id/descDetailTxt"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceLarge"
android_padding="5dp"
android_textColor="#0f0f0f"
android_minLines="4"
android_text="Space craft details...." />
<TextView
android_id="@+id/linkDetailTxt"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceMedium"
android_padding="5dp"
android_textColor="@color/colorPrimaryDark"
android_textStyle="italic"
android_text="Link" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
4. Download
Como executar
- Baixe o projeto.
- Você obterá um arquivo compactado, extraia-o.
- Abra o Android Studio.
- Agora feche, projeto já aberto.
- Na barra de Menu, clique em Arquivo > Novo > Importar Projeto.
- Agora escolha uma pasta de destino, de onde você deseja importar o projeto.
- Escolha um projeto Android.
- Agora clique em “OK“.
- Pronto, você acabou de importar o projeto, agora edite-o.
- Você precisará acessar o Firebase Console, criar o aplicativo, baixar o arquivo de configuração e adicionar ao seu projeto na pasta do aplicativo.