Android Firebase Realtime Datenbank mit RecyclerView Tutorial_

In diesem Beitrag wollen wir uns einige Beispiele für RecyclerView und Firebase Realtime Database ansehen. Im Wesentlichen geht es darum, wie man verschiedene CRUD-Operationen wie Hinzufügen, Abrufen und Anzeigen in RecyclerView durchführt.

Was ist Firebase Realtime Database?

Firebase Realtime Database ist einer der Dienste, die von der Firebase Platform bereitgestellt werden, die sich im Besitz von Google befindet.

Im Grunde ist es das, was wir ein Datenbank-BAAS oder ein Datenbank-Backend als Service nennen. Es wird in der Cloud gehostet.

Feuerwehr Live Übung in Nieder-Olm

Feuerwehr Live Übung in Nieder-Olm
Feuerwehr Live Übung in Nieder-Olm

Warum Firebase Realtime Database?

Firebase Realtime Database unterscheidet sich von vielen Datenbanken, die Sie vielleicht schon kennen, in vielerlei Hinsicht. Dies sind die Vorteile von Firebase Realtime Database.

  1. Sie wird in der Cloud gehostet, während die anderen wie SQLite und Realm lokal gehostet werden. Dies macht Firebase Realtime Database für viele Anwendungen zugänglich. Datenbanken wie SQLite und Realm sind innerhalb einer einzigen Anwendung lokalisiert. Firebase Realtime Database ist für viele Anwendungen zugänglich.
  2. Sie ist echtzeitfähig. Dies ist der größte Unterschied. Das bedeutet, dass Sie Daten speichern und die Daten in allen angeschlossenen Anwendungen automatisch und sofort aktualisiert werden. Das macht sie für viele Arten von Anwendungen wie Chat- und Messaging-Apps und Anwendungen, die eine sofortige Synchronisierung erfordern, sehr geeignet.
  3. Es speichert Daten im json-Format im Gegensatz zu Tabellen in Sqlite. Dies macht Firebase Realtime Database ziemlich skalierbar.
  4. Es gibt sowohl kostenlose als auch kostenpflichtige Pläne. Dies ist der beste Fall, denn dann können Sie es sowohl für Lern- als auch für kommerzielle Zwecke nutzen.

Was ist RecyclerView?

RecyclerView ist eine Android-Adapteransicht, die es uns ermöglicht, große Datensätze effizient darzustellen. Normalerweise benötigt man zum Rendern von Listendaten in Android eine Adapterview und einen Adapter. Der Adapterview ist das Listen-Widget und Beispiele sind ListView, Gridview, Spinner und natürlich RecyclerView.

Dann ist der Adapter normalerweise für die Verbindung des Adapterviews mit der Datenquelle verantwortlich. Und in der Tat kann man normalerweise benutzerdefinierte Layouts verwenden, um ein einzelnes Listenelement zu präsentieren. Dieses Layout wird auch innerhalb des Adapters aufgeblasen.

Lesen Sie mehr über den RecyclerView hier.

Warum RecyclerView?

Nun, wir haben gesagt, dass mehrere Adapterviews für die Datenpräsentation in Android verwendet werden können. Es gibt ListView, GridView, Spinner usw. ListView war bis zur Einführung von RecyclerView die beliebteste.

Heutzutage ist RecyclerView aufgrund seiner Flexibilität und Leistung der am häufigsten verwendete Adapterview. RecyclerView kann verwendet werden, um fast jede Art von Ansicht zu erstellen, von einer Listenansicht, zu einer Grid/Staggered-Ansicht, zu einer Tabellenansicht, zu einem Kalender usw.

Diese Tatsache macht es zu etwas ganz Besonderem und in vielen Szenarien verwendbar. Dennoch ist sie nicht viel schwieriger als die anderen Adapteransichten.

Verwendete Tools

Dieses Beispiel wurde mit den folgenden Tools geschrieben:

  • Microsoft Windows 8.1 – Dies ist mein Betriebssystem.
  • Android Studio – Dies ist meine IDE (Integerated Develpment Kit) von Jetbrains und Google.
  • Genymotion Emulator – Diesen benutzen wir, um unsere Anwendungen zu testen.
  • Sprache : Java – Java ist die beliebteste Programmiersprache.

1. Android Firebase => Simple RecyclerView – Speichern, Abrufen und Anzeigen

\Android Firebase Realtime Database recyclerView Tutorial_[/center]

Dies ist ein android firebase RecyclerView Tutorial. Wie man Daten in Firebase speichert, abruft und dann in einem einfachen Recyclerview anzeigt. Wir verwenden nur ein einziges Feld mit Daten.

Allgemeine Konzepte, die Sie von diesem Beispiel lernen.

Hier sind einige der Konzepte, die Sie aus diesem Tutorial lernen können:

  • Was ist Firebase und was ist [RecyclerView] (https://camposha.info/android/recyclerview) und warum werden sie verwendet.
  • Wie man Daten von edittext in die Google Firebase Realtime Datenbank speichert.
  • Wie man Daten aus der Firebase Datenbank abruft oder liest, indem man Ereignisse an eine DatabaseReference Instanz anhängt und dann eine Java Array-Liste auffüllt
  • Wie bindet man die abgerufenen Daten an eine Instanz der Unterklasse RecyclerView.Adapter.
  • Wie man eine Datenbank in Firebase erstellt und bearbeitet.
  • Firebase Beispielanwendungen mit Recyclerview.
  • Firebase Datenbank-Synchronisation

Spezifische Konzepte, die Sie lernen werden

  • Wie man die Firebase Datenbank Referenz verwendet.
  • Wie man ein Kind zur Firebase-Datenbankreferenz hinzufügt

Demo

Hier ist die Projektdemo für dieses Tutorial:

Einrichtung und Konfiguration

(a). Basic Activity Projekt erstellen
  1. Erstellen Sie zunächst ein neues Projekt in android studio.
(b). Firebase erstellen und Konfigurationsdatei herunterladen

Gehen Sie zur Firebase-Konsole, erstellen Sie eine Firebase-App, registrieren Sie Ihre App-ID und laden Sie die Datei "google-services.json" herunter. Fügen Sie sie zu Ihrem App-Ordner hinzu.

(c). Geben Sie die URL des Maven-Repositorys an

Gehen Sie zur Projektebene (Projektordner) build.gradle und

  1. Fügen Sie den Google Services Klassenpfad wie unten angegeben hinzu
  2. Maven-Repository-URL hinzufügen

// 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
}

Dies ermöglicht es uns, unsere Firebase von maven.google com zu holen. Firebase ist eine Bibliothek eines Drittanbieters und muss heruntergeladen werden, damit wir sie in unserem Projekt verwenden können.

(d). Firebase-Abhängigkeiten hinzufügen

Fügen Sie sie in Ihrer App-Ebene (App-Ordner) build.gradle müssen wir mehrere Abhängigkeiten hinzufügen. Wir haben Support-Bibliotheken wie appcompat, design und cardview hinzugefügt. AppCompat wird uns AppCompatActivity liefern, die Klasse, von der unsere MainActivity abgeleitet wird. Wir fügen sie mit der Anweisung Implementation hinzu.

Die "design"-Unterstützung gibt uns die "recyclerveiew", die unser Listen-Widget ist. Es ist das, was wir mit Daten füllen werden, die wir von unserer Firebase abfragen. Die cardview auf der anderen Seite wird uns erlauben, mit cardviews als unsere Elementansichten zu arbeiten. Der Recyclerview soll Cardviews enthalten.

Dann haben wir den Firebase Core und die Firebase Database hinzugefügt. Firebase remember ist eine Plattform, während die Firebase Database die Datenbank ist, in der wir unsere Daten speichern. Sie können spätere Versionen verwenden. Vergessen Sie jedoch nicht, die Google-Dienste anzuwenden, wie wir es getan haben.

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'

Stellen Sie sicher, dass Sie apply plugin: 'com.google.gms.google-services' wie oben.

2. Unser Java-Code

Wir schreiben dieses Beispiel in der Programmiersprache Java. Daher werden wir verschiedene Teile unserer Anwendung in mehrere Klassen entkoppeln.

(a). Unsere Model-Klasse
  • Ist unsere Datenobjektklasse
  • Muss einen leeren Konstruktor haben.
  • Sie können andere Konstruktoren erstellen, Daten an sie übergeben und sie verwenden.

Die Modell- oder Datenobjektklasse stellt im Grunde eine Klasse dar, die unsere Daten modelliert. Wenn Sie mit Daten jeglicher Art arbeiten, ist es immer eine gute Idee, die Daten in einer konkreten, einfachen Klasse darzustellen. Das Objekt dieser Klasse kann dann bei Bedarf abgefragt werden. Normalerweise haben diese Arten von Klassen sogenannte Accessor-Methoden. Diese Methoden sind immer öffentlich und bieten somit eine Möglichkeit, die Eigenschaften der Klasse, die immer privat sind, offen zu legen.

In unserem Fall haben wir eine Klasse namens "Spacecraft" erstellt. Diese Klasse hat eine einzige Eigenschaft, nämlich einen Namen, der den Namen des Raumschiffs enthält. Dann versehen wir unsere Klasse mit einem öffentlichen Standardkonstruktor. Dies ist eine Funktion, die normalerweise von Datenbank-Engines benötigt wird, die sich auf das Lesen des Datenobjekts verlassen, um das Datenbankschema automatisch zu generieren. Firebase Database tut dies definitiv, ebenso wie Realm, eine lokale Datenbank für Java und Android.

Dann versehen wir unsere Klasse mit einer getName und setName Accessor-Methode.

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). Unsere FirebaseHelper-Klasse
  • Im Grunde ist das unsere CRUD-Klasse.
  • Hier führen wir Lese- und Schreibvorgänge in der Firebase-Datenbank durch.
  • Um Daten zu persistieren, verwenden wir setValue().
  • Vor dem Aufruf der setValue()-Methode rufen wir push() auf, um sicherzustellen, dass wir die Daten an die Datenbank anhängen und nicht ersetzen.
  • Wir füllen eine einfache Arrayliste.

Wir haben diese Klasse, FirebaseHelper Klasse, erstellt, um uns das Speichern sowie das Abfragen oder Lesen von Daten aus Firebase zu ermöglichen. Wir beginnen mit der Definition des Pakets, das unsere Klasse aufnehmen soll. Dann fügen wir unsere Importe hinzu, einschließlich mehrerer Klassen aus "com.google.firebase.database".

Wir haben mehrere Instanzfelder definiert, darunter:

  1. DatabaseReference – Unsere Datenbank-Referenz.
  2. Boolescher Wert – um festzustellen, ob wir erfolgreich gespeichert haben oder nicht.
  3. ArrayList – Um unsere von Firebase abgerufenen Daten zu speichern.

Wir beginnen mit dem Empfang einer Datenbankreferenz über den Konstruktor. Dann weisen wir die Datenbankreferenz dem lokalen Instanzfeld zu, das wir gepflegt haben.

Daten in FirebaseDatabase speichern

Anschließend definieren wir eine Methode zum Speichern von Daten in der Firebase-Datenbank. Diese Methode erhält ein Spacecraft-Objekt als Parameter. Da wir das "Spacecraft"-Objekt von der Außenwelt erhalten, wäre es ideal, es zuerst auf Null zu überprüfen.

Um Daten in Firebase zu speichern

    db.child("Spacecraft").push().setValue(spacecraft);

In diesem Fall ist db unsere DatabaseReference. Wir erhalten seinen Kindknoten über die Methode child(). Dann übergeben wir den Namen unserer "Tabelle". Dann verwenden wir die Methode push(), um Daten an Firebase zu senden. Allerdings müssen wir den Wert, den wir pushen wollen, festlegen. Wir verwenden die Methode setValue um unser spacecraft Objekt zu setzen. Und so speichern wir die Daten in unserer Firebase-Datenbank. Beachten Sie, dass wir einen Try-Catch-Block verwendet haben, um eine DatabaseException abzufangen.

Daten aus der Firebase-Datenbank abrufen

Wir werden Daten von der Firebase Realtime Datenbank erhalten und eine ArrayList füllen. Später wird diese ArrayList dann als Datenquelle für unseren Recyclerview Adapter verwendet.

Um Daten von Firebase zu lesen, müssen wir einen ChildEventListener an unsere Datenbankreferenz anhängen. Dieser wird dann auf Änderungen in den Datenknoten hören. Wenn zum Beispiel ein Kindknoten hinzugefügt, geändert, entfernt oder gelöscht wird, erhalten wir Callback-Methoden, die unseren Daten-Snapshot enthalten. Wir können dann Daten aus diesen Daten-Snapshots lesen.

Bei jeder Iteration können Sie dann die Methode getValue des untergeordneten Daten-Schnappschusses aufrufen, um das Objekt zu erhalten. Das Lesen von Daten aus einem DataSnapshot-Objekt ist einfach. Man geht einfach in einer Schleife durch seine Unterobjekte:

 for (DataSnapshot ds : dataSnapshot.getChildren())
        {
            String name=ds.getValue(Spacecraft.class).getName();
            spacecrafts.add(name);
        }

Hier ist der vollständige Code:

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). Unsere MyViewHolder-Klasse
  • Ja, das ist unsere Viewholder-Klasse.
  • Hält Views zur Verwendung bereit

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);
    }
}

Das MyViewHolder ist unsere ViewHolder Klasse. Diese werden immer für das Recycling von Views durch den Recyclerview benötigt. Um jedoch eine Klasse in einen Recyclerview-Viewholder zu verwandeln, müssen wir von der Klasse Recyclerview.ViewHolder ableiten, wie Sie oben gesehen haben. Wir haben damit begonnen, mehrere Klassen einschließlich der Klasse RecyclerView selbst zu imprortng.

In unserer Klasse haben wir eine TextView mit dem Namen "NameTxt" gepflegt. Dann hat unsere MyViewHolder-Konstruktion ein View-Objekt aufgenommen. Dieses View-Objekt wurde dann an die Superklasse übergeben, die Recyclerview.ViewHolder ist.

Dann haben wir den "NameTxt" aus seiner Layout-Spezifikation referenziert.

9. Unsere MyAdapter-Klasse
  • Verantwortlich für Layout Inflation.
  • Auch für die Datenbindung an Views.

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();
    }
}

Adapter sind wichtig für die Art und Weise, wie Android mit der Sammlung von Daten arbeitet. Mobile Geräte, sei es HTC, Samsung, F7, Apple iOS, Infinix usw., alle von ihnen alle stark Apps, die Listen von Daten zu rendern müssen. Das liegt einfach in der Natur von Mobilgeräten. Der Bildschirm ist immer winzig und daher ist es angebracht, Elemente anzuzeigen, die gescrollt werden können.

Und RecyclerView ist die Nummer eins der Adapterviews für die Anzeige großer Datensätze. Diese Datensätze können aus der Cloud wie Firebase kommen. Und in der Tat kommen unsere Daten in diesem Fall aus der Firebase Realtime Datenbank. Wir haben also bisher eine ArrayList mit den Daten gefüllt, die wir bereits gesammelt haben. Nun ist es an der Zeit, diese Daten zu binden. Dafür benötigen wir einen Adapter.

Adapter:

  1. Erlauben uns Daten an unsere Adapterviews zu binden.
  2. Helfen uns beim Aufblasen von benutzerdefinierten Layouts in Views, so dass wir benutzerdefinierte Adapterviews entwerfen können.

Man macht einen Recyclerview Adapter indem man von RecyclerView.Adapter<MyViewHolder> ableitet. Der generische Parameter ist der ViewHolder. Die Ableitung von dieser Klasse wird uns zwingen drei Methoden zu überschreiben:

  1. getItemCount – Gibt die Anzahl der Elemente zurück, die im RecyclerView dargestellt werden.
  2. onCreateViewHolder – Hier findet das Aufblasen statt. Wir verwendenLayoutInflater für das Aufblasen.
  3. onBindViewHolder` – Hier binden wir Daten an die Widgets, die wir in der ViewHolder Klasse definiert haben.

In der Zwischenzeit hat unser Konstruktor ein Context-Objekt sowie eine Array-Liste mit unseren Daten erhalten.

(d). Unsere MainActivity
  • Launcher-Aktivität.
  • Verweist auf RecyclerView und setzt seinen LayoutManager sowie seinen Adapter.
  • Zeigt den Input Dialog beim Klick auf die FAB Schaltfläche.
  • Richtet unsere Firebase ein, indem sie die DatabaseReference initialisiert.

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. Unsere Layouts

(a). activity_main.xml

Dies ist unser Hauptlayout activity.

<?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

Hier fügen wir unsere Adapterview ein, in diesem Fall eine 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
  • definiert das Layout unserer Eingabedialoge

<?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

Dies ist unser RecyclerView Zeilenmodell. Dieses Layout wird in der Adapterklasse aufgeblasen.

<?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
  • Vergessen Sie nicht, die Berechtigung für das Internet in Ihrer Manifestdatei hinzuzufügen.

<verwendet die Berechtigung android_name="android.permission.INTERNET"/>

Herunterladen

Durchsuchen
Herunterladen

2. Android Firebase – RecyclerView Mehrere Felder

Android Firebase Datenbank RecyclerView Tutorial_ Dies ist ein Android Firebase Datenbank RecyclerView Tutorial. Wie man Daten in Firebase speichert, abruft und dann diese Daten in einem benutzerdefinierten RecyclerView anzeigt.

Dieses Mal verwenden wir mehrere Felder im Gegensatz zu einem einzelnen Feld wie im vorherigen Beispiel.

1. Einrichten

(a). Basic Activity Projekt erstellen
  1. Erstellen Sie zunächst ein neues Projekt in android studio. Gehen Sie zu Datei –> Neues Projekt.
(b).Firebase erstellen und Konfigurationsdatei herunterladen

Gehen Sie zur Firebase-Konsole, erstellen Sie eine Firebase-App, registrieren Sie Ihre App-ID und laden Sie die Datei "google-services.json" herunter. Fügen Sie sie zu Ihrem App-Ordner hinzu.

(c). Geben Sie die URL des Maven-Repositorys an

Gehen Sie zur Projektebene (Projektordner) build.gradle und

  1. Fügen Sie den Google Services Klassenpfad wie unten angegeben hinzu
  2. Fügen Sie die Maven-Repository-URL hinzu

// 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). Firebase-Abhängigkeiten hinzufügen

Fügen Sie sie in der App-Ebene (App-Ordner) build.gradle hinzu, dann

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'

Stellen Sie sicher, dass Sie apply plugin: 'com.google.gms.google-services' wie oben.

(e). AndroidManifest
  • Vergessen Sie nicht, die Berechtigung für das Internet in Ihrer Manifestdatei hinzuzufügen.

<?xml version="1.0" encoding="utf-8"?>
<manifest
    package="com.tutorials.hp.firebaserecyclermulti_items">

    <uses-permission android_name="android.permission.INTERNET"/>
    ....
</manifest>

2. Klassen

(a). Unsere Modellklasse
  • Ist unsere Datenobjektklasse
  • Muss einen leeren Konstruktor haben.
  • Sie können andere Konstruktoren erstellen, Daten an sie übergeben und sie verwenden

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). Unsere FirebaseHelper Klasse
  • Im Grunde ist das unsere CRUD-Klasse.
  • Hier führen wir Lese- und Schreibvorgänge in der Firebase-Datenbank durch.
  • Um Daten zu persistieren, verwenden wir setValue().
  • Vor dem Aufruf der Methode setValue() rufen wir push() auf, um sicherzustellen, dass wir die Daten an die Datenbank anhängen und nicht ersetzen.
  • Wir füllen eine Arrayliste mit Modellobjekten.

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). Unsere ViewHolder-Klasse
  • Hält die Views für uns zum Recyceln bereit.
  • Unterklassen 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. Unsere MyAdapter-Klasse

  • Verantwortlich für Layout Inflation.
  • Auch für die Datenbindung an Views.
  • Diese Klasse ist eine Unterklasse von 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). Unsere MainActivity
  • Launcher-Aktivität.
  • RecyclerView referenzieren und seinen LayoutManager setzen.
  • Setzt seinen Adapter.
  • Zeigt den Input Dialog beim Klick auf die FAB Schaltfläche.
  • Richtet unsere Firebase ein, indem wir die DatabaseReference initialisieren.

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. Unsere Layouts

(a). InputDialog.xml
  • definiert das Layout unserer Eingabedialoge

<?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
  • Wie jedes Ansichtselement erscheinen soll.

<?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 .

Browse
Download

3. Android Firebase – RecyclerView Master Detail [Open Activity]

Hallo, willkommen zu unserem Android Firebase RecyclerView Master Detail-Tutorial.

Dies ist ein Android Firebase Recyclerview Tutorial. Wie man Daten in Firebase speichert, abruft und dann diese Daten in einem benutzerdefinierten Gridview anzeigt.

  • Speichern von Daten aus edittext in google firebase Datenbank.
  • Abrufen der Daten durch Anhängen von Ereignissen an eine DatabaseReference-Instanz.
  • Binden Sie die Daten zu einem csutom Gridview mit einer BaseAdapter Unterklasse.
  • Handle die itemClicks der GridView.
  • Öffnen Sie eine neue Aktivität, wenn ein Grid-Element angeklickt wird.
  • Übergeben Sie Daten an diese neue Activity

Was ist die Firebase Realtime Datenbank?

Firebase Realtime Database ist ein Datenbank-Backend als Service, das in der Cloud gehostet wird und uns die Plattform bietet, um reichhaltige Anwendungen zu erstellen. Normalerweise sind wir daran gewöhnt, HTTP-Anfragen zu stellen, um Daten auf unseren Servern zu lesen oder zu schreiben, aber nicht in Firebase. Es verwendet eine Synchronisationstechnologie, die es ermöglicht, in Echtzeit zu arbeiten, aber trotzdem performant zu sein.

Hauptvorteile?

  • Seine Echtzeit.
  • Unabhängig von Plattformen.
  • Einfache Zugriffskontrolle.
  • Es ist eine NoSQL-Lösung und ist stark auf Leistung optimiert.
  • Hat Offline-Fähigkeit.
  • Es ist benutzerfreundlich.

Video-Tutorial Für weitere Erklärungen sehen Sie sich bitte unser Video-Tutorial unten an.

Einrichtung

(a). Grundlegendes Aktivitätsprojekt erstellen
  1. Erstellen Sie zunächst ein neues Projekt in android studio. Gehen Sie zu Datei –> Neues Projekt.
(b). Firebase erstellen und Konfigurationsdatei herunterladen

Gehen Sie zur Firebase-Konsole, erstellen Sie eine Firebase-App, registrieren Sie Ihre App-ID und laden Sie die Datei "google-services.json" herunter. Fügen Sie sie zu Ihrem App-Ordner hinzu.

(c). Geben Sie die URL des Maven-Repositorys an

Gehen Sie zur Projektebene (Projektordner) build.gradle und

  1. Fügen Sie den Google Services Klassenpfad wie unten angegeben hinzu
  2. Fügen Sie die Maven-Repository-URL hinzu

// 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). Firebase-Abhängigkeiten hinzufügen

Fügen Sie sie in Ihrer App-Ebene (App-Ordner) build.gradle hinzu, dann

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'

Stellen Sie sicher, dass Sie apply plugin: 'com.google.gms.google-services' wie oben.

(e). AndroidManifest.xml
  • Vergessen Sie nicht, die Berechtigung für das Internet in Ihre Manifestdatei aufzunehmen.

<?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>

Java-Klassen

(a). Raumschiff.java
  • Ist unsere Datenobjektklasse
  • Muss einen leeren Konstruktor haben.
  • Du kannst andere Konstruktoren erstellen, Daten an sie übergeben und sie verwenden

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
  • Im Grunde genommen unsere CRUD-Klasse.
  • Hier führen wir Lese- und Schreibvorgänge in der Firebase-Datenbank durch.
  • Um Daten zu erhalten, verwenden wir setValue().
  • Vor dem Aufruf der setValue()-Methode rufen wir push() auf, um sicherzustellen, dass wir die Daten an die Datenbank anhängen und nicht ersetzen.
  • Wir füllen eine Arrayliste mit Raumfahrzeugobjekten.

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
  • Ist unsere Viewholder-Klasse.
  • Hält die Ansichten, die in unserem RecyclerView angezeigt werden sollen.

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
  • Ist für die Layout Inflation verantwortlich.
  • Auch für die Datenbindung an Views.
  • Öffnet dann eine neue Activity und übergibt Daten an diese 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
  • Definiert für uns die Signatur für unsere onItemClick() Methode.

package com.tutorials.hp.firebaserecyclermdetail.m_UI;

public interface ItemClickListener {

    void onItemClick(int pos);
}

12. MainActivity.java

  • Launcher-Aktivität.
  • Verweist auf RecyclerView, setzt dessen Adapter.
  • Zeigt den Eingabedialog beim Klick auf die FAB-Schaltfläche an.
  • Richtet unsere Firebase ein, indem die DatabaseReference initialisiert wird.

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
  • Ja, die DetailActivity hier, um unsere Details zu zeigen.
  • Empfängt Daten von MainActivity via Intent.
  • Zeigt die Daten in TextViews an.

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();
            }
        });
    }

}

Layouts

(a). ActivityMain.xml
  • Enthält unsere ContentMain.xml
  • Definiert unseren schwebenden ActionButton.

<?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
  • Unsere Master-Ansicht

<?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
  • definiert das Layout unserer Eingabedialoge

<?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
  • definiert unsere benutzerdefinierten CardViews.

<?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). activity_detail.xml
  • Enthält unsere 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
  • Unsere Detail-Ansicht.

<?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 .

Browse
Download

Wie man läuft

  1. Laden Sie das Projekt herunter.
  2. Sie erhalten eine gezippte Datei, entpacken Sie sie.
  3. Öffnen Sie das Android Studio.
  4. Schließen Sie nun das bereits geöffnete Projekt.
  5. Klicken Sie in der Menüleiste auf Datei >Neu> Projekt importieren.
  6. Wählen Sie nun einen Zielordner, aus dem Sie das Projekt importieren möchten.
  7. Wählen Sie ein Android-Projekt.
  8. Klicken Sie nun auf "OK".
  9. Fertig, Sie haben das Projekt importiert und können es nun bearbeiten.
  10. Gehen Sie zur Firebase Console, erstellen Sie eine App, laden Sie die Konfigurationsdatei herunter und fügen Sie sie zu Ihrem Projekt im App-Ordner hinzu.