Android Firebase Realtime Database - 3 GridView Examples.


Android Firebase Realtime Database GridView Examples.

In this tutorial we are concerned with GridView and Firebase Realtime Database. We see how to perform CRUD operations against Firebase Realtime Database and show data in a GridView.

What is Firebase Realtime Database

Firebase Realtime database is a database backend as a service Cloud hosted solution that gives us the platform to build rich apps.Read more about Firebase Realtime Database here .

What is GridView?

GridView is an android widget that allows show data in grids. We can define the number of columns we want shown using the android:numColumns attribute.

1. Android Firebase GridView - Save From EditText,Retrieve

Android Firebase GridView  Tutorial.

The Plan

This is an android firebase gridview tutorial. How to save data to firebase,retrieve then show that data in a simple gridview.

  • Save data from edittext to google firebase database.
  • Retrieve the data by attaching events to a DatabaseReference instance.
  • Bind the data to a simple gridview using ArrayAdapter.

Setup

(a). Create Basic Activity Project
  1. First create a new project in android studio. Go to File --> New Project.
(b). Create Firebase and Download Configuration File

Head over to Firebase Console, create a Firebase App, Register your app id and download the google-services.json file. Add it to your app folder.

Add Config File

(c). Specify Maven repository URL

Head over to project level(project folder) build.gradle and

  1. Add Google services classpath as below
  2. Add maven repository url
// 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). Add Firebase Dependencies

Add them in you app level(app folder) build.gradle, then

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'

Make sure you apply plugin: 'com.google.gms.google-services' as above.

(e). AndroidManifest.xml

Our Classes

(a). Our Model class : Spacecraft
  1. Its our data object
package com.tutorials.hp.firebasesimplegridview.m_Model;

public class Spacecraft {
    String name;
    public Spacecraft() {
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
(b). Our FirebaseHelper class

Where we perform :

  • Writes using push() and setValue() methods.
  • We retrieve data by attaching childeventlistener to our DatabaseReference instance.
  • Fill a simple arraylist with this data
package com.tutorials.hp.firebasesimplegridview.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.firebasesimplegridview.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;
    }

    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;

    }

    //RETRIEVE
    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). Our MainActivity
  • Launcher activity
  • Bind data to gridview
  • Show input dialog
package com.tutorials.hp.firebasesimplegridview;

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.Toolbar;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.Toast;

import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.tutorials.hp.firebasesimplegridview.m_FireBase.FirebaseHelper;
import com.tutorials.hp.firebasesimplegridview.m_Model.Spacecraft;

public class MainActivity extends AppCompatActivity {

    GridView gv;
    ArrayAdapter<String> adapter;
    DatabaseReference db;
    FirebaseHelper helper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        gv= (GridView) findViewById(R.id.gv);

        //SETUP FIREBASE
        db= FirebaseDatabase.getInstance().getReference();
        helper=new FirebaseHelper(db);

        //adapter
        adapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,helper.retrieve());
        gv.setAdapter(adapter);

        gv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(MainActivity.this, helper.retrieve().get(position), Toast.LENGTH_SHORT).show();
            }
        });

        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 Rirebase");
        d.setContentView(R.layout.input_dialog);

        final EditText nameEditTxt= (EditText) d.findViewById(R.id.nameEditText);
        Button saveBtn= (Button) d.findViewById(R.id.saveBtn);

        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 != null && name.length()>0)
                {
                    if(helper.save(s))
                    {
                        nameEditTxt.setText("");
                        adapter=new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,helper.retrieve());
                        gv.setAdapter(adapter);

                    }
                }else
                {
                    Toast.makeText(MainActivity.this, "Name Cannot be empty", Toast.LENGTH_SHORT).show();
                }

            }
        });

        d.show();
    }

}

Our Layouts

(a). activity_main.xml

Our main activity layout.

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.tutorials.hp.firebasesimplegridview.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

This layout will be included into our activity_main.xml. We add our gridview which is our adapterview here.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    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.firebasesimplegridview.MainActivity"
    tools:showIn="@layout/activity_main">

    <GridView
        android:id="@+id/gv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:numColumns="3" />
</RelativeLayout>
(c). input_dialog.xml

Basically our input form layout. Will be used to insert data into Firebase Database.

  • Input Dialog
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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="20dp">

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

Download

Resource Link
GitHub Browse Browse
GitHub Download Link Download
Video Tutorial Video

2. Android Firebase => GridView - Save,Retrieve Multiple Fields.

This is a Firebase example to help us explore how to work with multiple fields.

In a previous class we'd looked at saving and retrieving a single field, so let's see many fields in this example.

The Plan

This is an android firebase gridview tutorial.We had actually done an android firebase tutorial earler with a GridView.However in that case we using a simple field.Well that's not terribly practical. How to save data to firebase,retrieve then show that data in a simple gridview.

  • Save data from several edittext to google firebase database.
  • Retrieve the data by attaching events to a DatabaseReference instance.
  • Fill a simple array list and pass it over to the custom adapter.To be bound.
  • Bind the data to our Custom gridview using CustomAdapter.Our custom adapter derives from BaseAdapter.

Project Summary

No. File Major Responsibility
1. Spacecraft.java Represents a single Spacecraft and it's properties like name,propellant and description.
2. FirebaseHelper.java This class has allows us perform Firebase CRUD operations.
3. CustomAdapter.java Our adapter class
4. MainActivity.java Our Master Activity. It shows the grid of Spacecrafts
5. activity_main.xml Our Master Activity's layout.
6. content_main.xml Our Master Activity's content detail.
7. input_dialog.xml Our input dialog layout.
8. model.xml Each GridView's grid model.
9. build.gradle(app) We add Firebase dependencies here.

Setting Up

(a). Create Basic Activity Project
  1. First create an empty project in android studio. Go to File --> New Project.
(b). Add Firebase Configurations

Go ahead create you Firebase Database realtime in your Firebase account.

Then download the google.json file and add it to your project at the app level:

(c). Add Dependencies

Go to your build.gradle and add dependencies.You many use later verisons of Firbese than we used.Make sure you also apply the googleservices plugin:

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:9.0.2'
    compile 'com.google.firebase:firebase-database:9.0.2'
}
apply plugin: 'com.google.gms.google-services'
(d). AndroidManifest.xml

Finally add internet permission in your AndroidManifest.xml as we will be accessing internet:

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

XML Layouts

Here are our layouts for this project:

(a). activity_main.xml
  • This layout gets inflated to MainActivity user interface.
  • It includes the content_main.xml.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.tutorials.hp.firebasegridviewmulti_items.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

This layout gets included in your activity_main.xml. We define our GridView here.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    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.firebasegridviewmulti_items.MainActivity"
    tools:showIn="@layout/activity_main">

    <GridView
        android:id="@+id/gv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:numColumns="2" />
</RelativeLayout>
(c). input_dialog.xml

This in our input view. We have a couple of EditTexts and button to save data to Firebase.

This layout will be inflated into a Custom Dialog.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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

This layout will get inflated into GridView View items or grids.

Each grid is basically a CardView with several TextViews. Each Grid will represents a single Spacecraft object.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    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>

Well those are our layouts.

5. Java Classes

(a). Spacecraft.java

This is our data object class. Here's its responsibilities:

No. Responsibility
1. Represents a Single Spacecraft
2. Set Spacecraft properties: name,propellant and description.
3. Get Spacecraft properties: name,propellant and description.
package com.tutorials.hp.firebasegridviewmulti_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). FirebaseHelper.java

This class allows us perform save and retrieve data to Firebase Realtime database.

No. Responsibility
1. Keep hold of three Objects: DatabaseReference,a Boolean saved value, and an ArrayList of Spacecrafts.
2. Obtain a DatabaseReference object via the constructor and Assign it to our local db data member.
3. Take a Spacecraft object and save it to Firebase this returning a Boolean indicating success or failure.
4. Loop through DataSnapshot children nodes obtaining all the Spacecraft objects from Firebase and fill our local arraylist with those objects.
5. Listen to Firebase Children mutation events like when a DataSnapshot child has been added, moved, removed, changed or cancelled. This allows us to fetch data in realtime.
package com.tutorials.hp.firebasegridviewmulti_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.firebasegridviewmulti_items.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<>();

    /*
   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). CustomAdapter.java

This is our adapter class. It derives from BaseAdapter.

No. Responsibility
1. This class will maintain a Context object that will be used to during layout inflation. Furthermore we declare an ArrayList of Spacecrafts that will be bound to our GridView.
2. Receive a Context and ArrayList of Spacecrafts from outside and assign them to our local instance fields.
3. Return data list count,Item and Item Identifier.
4. Inflate our model.xml layout and return it as a View when the getView() is called.
package com.tutorials.hp.firebasegridviewmulti_items.m_UI;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.tutorials.hp.firebasegridviewmulti_items.R;
import com.tutorials.hp.firebasegridviewmulti_items.m_Model.Spacecraft;

import java.util.ArrayList;

/*
 * 1. where WE INFLATE OUR MODEL LAYOUT INTO VIEW ITEM
 * 2. THEN BIND DATA
 */
public class CustomAdapter extends BaseAdapter {
    Context c;
    ArrayList<Spacecraft> spacecrafts;

    public CustomAdapter(Context c, ArrayList<Spacecraft> spacecrafts) {
        this.c = c;
        this.spacecrafts = spacecrafts;
    }

    @Override
    public int getCount() {
        return spacecrafts.size();
    }

    @Override
    public Object getItem(int position) {
        return spacecrafts.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(convertView==null)
        {
            convertView= LayoutInflater.from(c).inflate(R.layout.model,parent,false);
        }

        TextView nameTxt= (TextView) convertView.findViewById(R.id.nameTxt);
        TextView propTxt= (TextView) convertView.findViewById(R.id.propellantTxt);
        TextView descTxt= (TextView) convertView.findViewById(R.id.descTxt);

        final Spacecraft s= (Spacecraft) this.getItem(position);

        nameTxt.setText(s.getName());
        propTxt.setText(s.getPropellant());
        descTxt.setText(s.getDescription());

        //ONITECLICK
        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(c,s.getName(),Toast.LENGTH_SHORT).show();
            }
        });

        return convertView;
    }
}
(d). MainActivity.java

This is our MainActivity, our launcher activity.

No. Responsibility
1. It will maintain a couple of objects as instance fields including: DatabaseReference,FirebaseHelper,CustomAdapter, GridView and three EditTexts.
2. Define a method to instantiate our Dialog object, set it's title, set its ConteView and finally show it.This dialog is our input dialog with edittexts and save/retrieve buttons.
3. Search all the input widgets defined in input_dialog.xml and assign them to their respective instance objects.These include EditTexts and Buttons.
4. Listen to Save button click events, then obtain edittext values, assign those values to a Spacecraft object and with the help of FirebaseHelper instance send that object to Firebase realtime database.
5. Override the onCreate() method,call it's super equivalence.
6. Find Toolbar in our layout and use it as our actionbar.
7. Get FirebaseDatabase instance then it's reference and pass it to our FirebaseHelper constructor.
8. Instantiate CustomAdapter, find Gridview from our layout, then assign the adapter to the Gridview.
9. Listen to FAB button click event and show the input dialog.
package com.tutorials.hp.firebasegridviewmulti_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.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.Toast;

import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.tutorials.hp.firebasegridviewmulti_items.m_FireBase.FirebaseHelper;
import com.tutorials.hp.firebasegridviewmulti_items.m_Model.Spacecraft;
import com.tutorials.hp.firebasegridviewmulti_items.m_UI.CustomAdapter;
/*
1.INITIALIZE FIREBASE DB
2.INITIALIZE UI
3.DATA INPUT
 */
public class MainActivity extends AppCompatActivity {

    DatabaseReference db;
    FirebaseHelper helper;
    CustomAdapter adapter;
    GridView gv;
    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);

        gv= (GridView) findViewById(R.id.gv);

        //INITIALIZE FIREBASE DB
        db= FirebaseDatabase.getInstance().getReference();
        helper=new FirebaseHelper(db);

         //ADAPTER
        adapter=new CustomAdapter(this,helper.retrieve());
        gv.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 CustomAdapter(MainActivity.this,helper.retrieve());
                        gv.setAdapter(adapter);

                    }
                }else
                {
                    Toast.makeText(MainActivity.this, "Name Must Not Be Empty", Toast.LENGTH_SHORT).show();
                }

            }
        });

        d.show();
    }

}

4. Download

Resource Link
GitHub Browse Browse
GitHub Download Link Download

3. Android Firebase => GridView MasterDetail - Save,Read,Show

This is an android firebase tutorial. The aim is to write, read and show data in a GridView.

User can then click a particular gridview item and move to a new activity transferring data over there.

The Plan

This is an android firebase gridview tutorial. How to save data to firebase,retrieve then show that data in a custom gridview.

  • Save data from edittext to google firebase database.
  • Retrieve the data by attaching events to a DatabaseReference instance.
  • Bind the data to a csutom gridview using a BaseAdapter subclass.
  • Handle the GridView's itemClicks.
  • Open new Activity when a grid item is clicked.
  • Pass data to that new activity

Let's go.

Project Summary

No. File Major Responsibility
1. Spacecraft.java Represents a single Spacecraft and it's properties like name,propellant and description.
2. FirebaseHelper.java This class has allows us perform Firebase CRUD operations.
3. CustomAdapter.java Our adapter class
4. DetailActivity.java Our Detail Activity to show a single spacecraft's details.
5. MainActivity.java Our Master Activity. It shows the grid of Spacecrafts
6. activity_main.xml Our Master Activity's layout.
7. content_main.xml Our Master Activity's content detail.
8. activity_detail.xml Our Detail Activity's main layout.
9. content_detail.xml Our Detail Activity's content layout.
10. input_dialog.xml Our input dialog layout.
11. model.xml Each GridView's grid model.
(a). Create Basic Activity Project
  1. First create an empty project in android studio. Go to File --> New Project.
(b). Add Firebase Configurations

Go ahead create you Firebase Database realtime in your Firebase account.

Then download the google.json file and add it to your project at the app level:

(b). Add Dependencies

In your dependencies add Firebase dependencies then apply the googleservices plugin as below:

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:9.0.2'
    compile 'com.google.firebase:firebase-database:9.0.2'
}
apply plugin: 'com.google.gms.google-services'
(c). AndroidManifest.xml

Finally add internet permission in your AndroidManifest.xml as we will be accessing internet:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tutorials.hp.firebasegridviewmdetail">

    <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="@string/title_activity_detail"
            android:theme="@style/AppTheme.NoActionBar"></activity>
    </application>

</manifest>

(d). Create Second Activity

Go ahead create a SecondActivity that will be used as the Detail View.

It will display selected Spacecraft details.

We'll look at its source later. However note that it will add two XML layouts: activity_detail and content_detail to our layout resources.

2. Our Layouts

Here are our layouts for this project:

(a). activity_main.xml
  • This layout gets inflated to MainActivity user interface.
  • It includes the content_main.xml.
  • MainActivity is our Master View.
(b). content_main.xml

This layout gets included in your activity_main.xml. We define our GridView here.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    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.firebasegridviewmdetail.MainActivity"
    tools:showIn="@layout/activity_main">

    <GridView
        android:id="@+id/gv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:numColumns="2"
         />
</RelativeLayout>
(c). activity_detail.xml

Our SecondActivity's layout. Virtually the same as the activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.tutorials.hp.firebasegridviewmdetail.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>
(d). content_detail.xml

The SecondActivity's content layout.

Will be included into the activity_detail.xml.

We add a CardView with an imageview and TextView that will be used to show the details of our Spacecraft.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    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.firebasegridviewmdetail.DetailActivity"
    tools:showIn="@layout/activity_detail">

    <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal" android:layout_width="match_parent"
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        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" />

                    <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...." />

                </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/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>
(e). input_dialog.xml

This layout will be inflated into a dialog. Our input dialog.

Users can then perform CRUD via this layout.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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>
(f). model.xml

Our GridView will have images and text from our Firebase. We therefore need to create a custom model layout for each Grid.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    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>

6. Java Classes

Android projects get written in Java so let's write some Java code for our Firebase project.

(a). Spacecraft.java

This is our data object class. Here's its responsibilities:

No. Responsibility
1. Represents a Single Spacecraft
2. Set Spacecraft properties: name,propellant and description.
3. Get Spacecraft properties: name,propellant and description.
package com.tutorials.hp.firebasegridviewmdetail.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

This class allows us perform save and retrieve data to Firebase Realtime database.

No. Responsibility
1. Keep hold of three Objects: DatabaseReference,a Boolean saved value, and an ArrayList of Spacecrafts.
2. Obtain a DatabaseReference object via the constructor and Assign it to our local db data member.
3. Take a Spacecraft object and save it to Firebase this returning a Boolean indicating success or failure.
4. Loop through DataSnapshot children nodes obtaining all the Spacecraft objects from Firebase and fill our local arraylist with those objects.
5. Listen to Firebase Children mutation events like when a DataSnapshot child has been added, moved, removed, changed or cancelled. This allows us to fetch data in realtime.
package com.tutorials.hp.firebasegridviewmdetail.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.firebasegridviewmdetail.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 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). CustomAdapter.java

This is our adapter class. It derives from BaseAdapter.

No. Responsibility
1. This class will maintain a Context object that will be used to during layout inflation. Furthermore we declare an ArrayList of Spacecrafts that will be bound to our GridView.
2. Receive a Context and ArrayList of Spacecrafts from outside and assign them to our local instance fields.
3. Return data list count,Item and Item Identifier.
4. Inflate our model.xml layout and return it as a View when the getView() is called.
5. Listen to the inflated View click event and open our Master activity.
6. Pass the clicked spacecraft's details to the Detail Activity.
package com.tutorials.hp.firebasegridviewmdetail.m_UI;

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.tutorials.hp.firebasegridviewmdetail.DetailActivity;
import com.tutorials.hp.firebasegridviewmdetail.R;
import com.tutorials.hp.firebasegridviewmdetail.m_Model.Spacecraft;

import java.util.ArrayList;

/*
 * 1. where WE INFLATE OUR MODEL LAYOUT INTO VIEW ITEM
 * 2. THEN BIND DATA
 */
public class CustomAdapter extends BaseAdapter {
    Context c;
    ArrayList<Spacecraft> spacecrafts;

    public CustomAdapter(Context c, ArrayList<Spacecraft> spacecrafts) {
        this.c = c;
        this.spacecrafts = spacecrafts;
    }

    @Override
    public int getCount() {
        return spacecrafts.size();
    }

    @Override
    public Object getItem(int position) {
        return spacecrafts.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(convertView==null)
        {
            convertView= LayoutInflater.from(c).inflate(R.layout.model,parent,false);
        }

        TextView nameTxt= (TextView) convertView.findViewById(R.id.nameTxt);
        TextView propTxt= (TextView) convertView.findViewById(R.id.propellantTxt);
        TextView descTxt= (TextView) convertView.findViewById(R.id.descTxt);

        final Spacecraft s= (Spacecraft) this.getItem(position);

        nameTxt.setText(s.getName());
        propTxt.setText(s.getPropellant());
        descTxt.setText(s.getDescription());

        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //OPEN DETAIL
                openDetailActivity(s.getName(),s.getDescription(),s.getPropellant());
            }
        });

        return convertView;
    }

    //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);
    }
}
(d). SecondActivity.java

This is our DetailActivity. It will show the details of our Spacecraft.

Here's it's responsibilities and how it works:

No. Responsibility
1. Maintain three TextView objects as private instance fields that will be used to show Spacecraft details.
2. Override the onCreate() method. Call the super class version of onCreate() as well.
3. Inflate the activity_detail via the setContentView() to a View object and set it as the detail Activity's main UI.
4. Find the toolbar from activity_detail and set it as the actionbar of our SecondActivity.
5. Find TextViews defined in the content_detail.xml and assign them to our local TextView objects.
6. Retrieve the Intent assoicated with our SecondActivity via the getIntent() call.
7. Obtain name, description and propellant of our Spacecraft via the getExtras() method calls of our Intent.Then set those values to our TextView objects.
package com.tutorials.hp.firebasegridviewmdetail;

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();
            }
        });
    }
}
(e). MainActivity.java

This is our MainActivity. Our project has two activities and this is the main one. It will be the one launched when we launch our application.

It is also our Master View and will contain a grid of Spacecraft objects.

No. Responsibility
1. It will maintain a couple of objects as instance fields including: DatabaseReference,FirebaseHelper,CustomAdapter, GridView and three EditTexts.
2. Define a method to instantiate our Dialog object, set it's title, set its ConteView and finally show it.This dialog is our input dialog with edittexts and save/retrieve buttons.
3. Search all the input widgets defined in input_dialog.xml and assign them to their respective instance objects.These include EditTexts and Buttons.
4. Listen to Save button click events, then obtain edittext values, assign those values to a Spacecraft object and with the help of FirebaseHelper instance send that object to Firebase realtime database.
5. Override the onCreate() method,call it's super equivalence.
6. Find Toolbar in our layout and use it as our actionbar.
7. Get FirebaseDatabase instance then it's reference and pass it to our FirebaseHelper constructor.
8. Instantiate CustomAdapter, find Gridview from our layout, then assign the adapter to the Gridview.
9. Listen to FAB button click event and show the input dialog.
package com.tutorials.hp.firebasegridviewmdetail;

import android.app.Dialog;
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.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.Toast;

import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.tutorials.hp.firebasegridviewmdetail.m_FireBase.FirebaseHelper;
import com.tutorials.hp.firebasegridviewmdetail.m_Model.Spacecraft;
import com.tutorials.hp.firebasegridviewmdetail.m_UI.CustomAdapter;

/*
1.INITIALIZE FIREBASE DB
2.INITIALIZE UI
3.DATA INPUT
 */
public class MainActivity extends AppCompatActivity {

    DatabaseReference db;
    FirebaseHelper helper;
    CustomAdapter adapter;
    GridView gv;
    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);

        gv= (GridView) findViewById(R.id.gv);

        //INITIALIZE FIREBASE DB
        db= FirebaseDatabase.getInstance().getReference();
        helper=new FirebaseHelper(db);

        //ADAPTER
        adapter=new CustomAdapter(this,helper.retrieve());
        gv.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 CustomAdapter(MainActivity.this,helper.retrieve());
                        gv.setAdapter(adapter);
                    }
                }else
                {
                    Toast.makeText(MainActivity.this, "Name Must Not Be Empty", Toast.LENGTH_SHORT).show();
                }
            }
        });

        d.show();
    }
}

Download

Resource Link
GitHub Browse Browse
GitHub Download Link Download
Video Tutorial Video

How To Run

  1. Download the project.
  2. You'll get a zipped file,extract it.
  3. Open the Android Studio.
  4. Now close, already open project.
  5. From the Menu bar click on File >New> Import Project.
  6. Now Choose a Destination Folder, from where you want to import project.
  7. Choose an Android Project.
  8. Now Click on “OK“.
  9. Done, your done importing the project,now edit it.
  10. You'll need to head over to Firebase Console, create app, then download configuration file and add to your project in the app folder.You also have to allow writes and reads from the FirebaseDatabase without authentication.

How do You Feel after reading this?

According to scientists, we humans have 8 primary innate emotions: joy, acceptance, fear, surprise, sadness, disgust, anger, and anticipation. Feel free to tell us how you feel about this article using these emotes or via the comment section. This feedback helps us gauge our progress.

Help me Grow.

I set myself some growth ambitions I desire to achieve by this year's end regarding this website and my youtube channel. Am halfway. Help me reach them by:




Recommendations


What do You Think


Previous Post Next Post