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.

Depois do truque de @kingarturo23, veio a Mágica de Arrascaeta

Depois do truque de @kingarturo23, ...
Depois do truque de @kingarturo23, veio a Mágica de Arrascaeta

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.

  1. 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.
  2. É 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.
  3. Armazena dados em formato json ao contrário de tabelas em sqlite. Isso torna o Firebase Realtime Database bastante escalável.
  4. 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
  1. 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

  1. Adicione o caminho de classe dos serviços do Google conforme abaixo
  2. 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:

  1. DatabaseReference — Nossa referência de banco de dados.
  2. Valor booleano – para determinar se salvamos com sucesso ou não.
  3. 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:

  1. Permita-nos vincular dados às nossas visualizações de adaptador.
  2. 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:

  1. getItemCount – Para retornar o número de itens a serem renderizados no recyclerview.
  2. onCreateViewHolder – É aqui que ocorre a inflação. UsamosLayoutInflater para a inflação.
  3. 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

Procurar
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
  1. 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

  1. Adicione o caminho de classe dos serviços do Google conforme abaixo
  2. 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

Procurar
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
  1. 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

  1. Adicione o caminho de classe dos serviços do Google conforme abaixo
  2. 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

Procurar
Download

Como executar

  1. Baixe o projeto.
  2. Você obterá um arquivo compactado, extraia-o.
  3. Abra o Android Studio.
  4. Agora feche, projeto já aberto.
  5. Na barra de Menu, clique em Arquivo > Novo > Importar Projeto.
  6. Agora escolha uma pasta de destino, de onde você deseja importar o projeto.
  7. Escolha um projeto Android.
  8. Agora clique em “OK“.
  9. Pronto, você acabou de importar o projeto, agora edite-o.
  10. Você precisará acessar o Firebase Console, criar o aplicativo, baixar o arquivo de configuração e adicionar ao seu projeto na pasta do aplicativo.