This is the activity for :

  1. Creating a New Scientist.
  2. Updating an Existing Scientit.
  3. Deleting an Existing scientist.

We are re-using the same activity intelligently for doing all those. This will save us from alot of repetitive coding. All we need do is inflate our menu resources based on the intended purpose of the activity.

For example if the activity is opened with a null object being passed along, then we know the activity is opened for adding a new scientist. Thus we inflate the new_item_menu.xml from our menu resources.

On the other hand if the activity is opened with a Scientist object being passed along, then we know the activity is opened for the sake of editing or deleting that scientist. Thus we inflate the edit_item_menu.xml. All the various widgets remain the same.

Video Lesson

Steps

Step 1: Create menus

Create a menu folder under the resources if you haven’t created one.Call it menu.

(a). new_tem_menu.xml

Create a menu file called new_item_menu.xml and add the following code:

<?xml version="1.0" encoding="utf-8"?>
<!-- Options menu for the CRUDActivity -->
<menu 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"
    tools:context=".views.ui.CRUDActivity">

    <item
        android:id="@+id/insertMenuItem"
        android:title="SAVE"
        android:icon="@drawable/m_add"
        app:showAsAction="always" />
    <item
        android:id="@+id/viewAllMenuItem"
        android:title="VIEW ALL"
        android:icon="@drawable/m_list"
        app:showAsAction="always" />
</menu>

(b). edit_item_menu.xml

Create a file called edit_item_menu.xml and add the following code:

<?xml version="1.0" encoding="utf-8"?>
<!-- Options menu for the CRUDActivity -->
<menu 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"
    tools:context=".views.ui.CRUDActivity">

    <item
        android:id="@+id/editMenuItem"
        android:title="SAVE"
        android:icon="@drawable/m_done"
        app:showAsAction="always" />
    <item
        android:id="@+id/deleteMenuItem"
        android:title="DELETE"
        android:icon="@drawable/m_delete"
        app:showAsAction="always" />
    <item
        android:id="@+id/viewAllMenuItem"
        android:title="VIEW ALL"
        android:icon="@drawable/m_list"
        app:showAsAction="ifRoom" />
</menu>

Step 2: Create XML Layout.

Go under the layout folder in your resources and add the following code in a file called activity_crud.xml.

(a). activity_crud.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:background="@android:color/holo_red_light"
    tools:context=".view.ui.CRUDActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingBottom="5dp"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"
        android:paddingTop="5dp">

        <TextView
            android:id="@+id/headerTxt"
            fontPath="fonts/Roboto-Bold.ttf"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="Scientists Editing Page"
            android:textAlignment="center"
            android:textAppearance="@style/TextAppearance.AppCompat.Large"
            android:textColor="@color/white"
            tools:ignore="MissingPrefix" />

        <androidx.cardview.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/card_margin"
            app:cardBackgroundColor="@color/white">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="@dimen/text_padding"
                    android:text="INSTRUCTIONS"
                    android:textAppearance="@style/TextAppearance.AppCompat.Title"
                    android:textColor="@color/skyblue" />

                <TextView
                    android:id="@+id/instructionsTV"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="@dimen/text_padding"
                    android:text="Provide the Scientist details in the edittext then click the save button in the toolbar. Some fields like name and galaxy must be provided." />

            </LinearLayout>

        </androidx.cardview.widget.CardView>

        <androidx.cardview.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/card_margin">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="@dimen/text_padding"
                    android:text="Personal Details"
                    android:textAppearance="@style/TextAppearance.AppCompat.Title"
                    android:textColor="@color/niceGreenish"
                    tools:ignore="MissingPrefix" />

                <EditText
                    android:id="@+id/nameTxt"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="16dp"
                    android:layout_marginTop="16dp"
                    android:hint="Name"
                    tools:ignore="MissingPrefix" />

                <EditText
                    android:id="@+id/descriptionTxt"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="16dp"
                    android:layout_marginTop="16dp"
                    android:hint="Description"
                    android:minLines="3"
                    tools:ignore="MissingPrefix" />

            </LinearLayout>

        </androidx.cardview.widget.CardView>

        <androidx.cardview.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/card_margin">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="@dimen/text_padding"
                    android:text="Residence Details"
                    android:textAppearance="@style/TextAppearance.AppCompat.Title"
                    android:textColor="@color/niceGreenish" />

                <EditText
                    android:id="@+id/galaxyTxt"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="16dp"
                    android:layout_marginTop="16dp"
                    android:hint="Galaxy"
                    tools:ignore="MissingPrefix" />

                <EditText
                    android:id="@+id/starTxt"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="16dp"
                    android:layout_marginTop="16dp"
                    android:hint="Star"
                    tools:ignore="MissingPrefix" />
            </LinearLayout>

        </androidx.cardview.widget.CardView>

        <androidx.cardview.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/card_margin">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="@dimen/text_padding"
                    android:text="TimeLine Details"
                    android:textAppearance="@style/TextAppearance.AppCompat.Title"
                    android:textColor="@color/niceGreenish" />

                <android.helper.DateTimePickerEditText
                    android:id="@+id/dobTxt"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_margin="@dimen/text_padding"
                    android:hint="Date of Birth"
                    tools:ignore="MissingPrefix" />
            </LinearLayout>

        </androidx.cardview.widget.CardView>

    </LinearLayout>

</ScrollView>

Step 3: Java Code

Now create a class called CRUDActivity.java under the Views package.

(a). CRUDActivity.java

package info.camposha.roomlivedatacrudapp.view.ui;

import android.content.Context;
import android.helper.DateTimePickerEditText;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NavUtils;
import androidx.lifecycle.ViewModelProviders;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import info.camposha.roomlivedatacrudapp.R;
import info.camposha.roomlivedatacrudapp.data.model.Scientist;
import info.camposha.roomlivedatacrudapp.common.Utils;
import info.camposha.roomlivedatacrudapp.viewmodel.ScientistViewModel;
import io.github.inflationx.viewpump.ViewPumpContextWrapper;

public class CRUDActivity extends AppCompatActivity {
    //we'll have several instance fields
    private EditText nameTxt, descriptionTxt, galaxyTxt, starTxt;
    private TextView headerTxt;
    private DateTimePickerEditText dobTxt;
    private final Context c = CRUDActivity.this;
    private ScientistViewModel scientistViewModel;
    private Scientist receivedScientist;

    private void insertScientist(String name, String description, String galaxy,
                                 String star, String dob) {
        Scientist scientist = new Scientist();
        scientist.setId(String.valueOf(System.currentTimeMillis()));
        scientist.setName(name);
        scientist.setDescription(description);
        scientist.setGalaxy(galaxy);
        scientist.setStar(star);
        scientist.setDob(dob);

        Long result = scientistViewModel.insert(scientist);
        if (result != null) {
            if (result > -1) {
                Utils.clearEditTexts(nameTxt, descriptionTxt, galaxyTxt, starTxt, dobTxt);
                Utils.show(this, "INSERT SUCCESSFUL");
            } else {
                Utils.show(this, "INSERT UNSUCCESSFUL");
            }
        } else {
            Utils.show(this, "UNSUCCESSFUL. ERRORED OCCURED");
        }

    }

    private void updateScientist(String name, String description, String galaxy,
                                 String star, String dob) {
        receivedScientist.setName(name);
        receivedScientist.setDescription(description);
        receivedScientist.setGalaxy(galaxy);
        receivedScientist.setStar(star);
        receivedScientist.setDob(dob);
        Integer result = scientistViewModel.update(receivedScientist);
        if (result != null) {
            if (result > 0) {
                Utils.show(this, "UPDATE SUCCESSFUL");
            } else {
                Utils.show(this, "UPDATE UNSUCCESSFUL");
            }
        } else {
            Utils.show(this, "UNSUCCESSFUL. ERRORED OCCURED");
        }
    }

    private void initializeWidgets() {
        headerTxt = findViewById(R.id.headerTxt);
        nameTxt = findViewById(R.id.nameTxt);
        descriptionTxt = findViewById(R.id.descriptionTxt);
        galaxyTxt = findViewById(R.id.galaxyTxt);
        starTxt = findViewById(R.id.starTxt);

        dobTxt = findViewById(R.id.dobTxt);
        dobTxt.setFormat(Utils.DATE_FORMAT);
    }

    private void insertData() {
        String name, description, galaxy, star, dob;
        if (Utils.validate(nameTxt, descriptionTxt, galaxyTxt)) {
            name = nameTxt.getText().toString();
            description = descriptionTxt.getText().toString();
            galaxy = galaxyTxt.getText().toString();
            star = starTxt.getText().toString();

            if (dobTxt.getDate() != null) {
                Date date=dobTxt.getDate();
                dob = dobTxt.getFormat().format(dobTxt.getDate());
            } else {
                dobTxt.setError("Invalid Date");
                dobTxt.requestFocus();
                return;
            }

            insertScientist(name, description, galaxy, star, dob);

        }
    }
    private void updateData() {
        String name, description, galaxy, star, dob;
        if (Utils.validate(nameTxt, descriptionTxt, galaxyTxt)) {
            name = nameTxt.getText().toString();
            description = descriptionTxt.getText().toString();
            galaxy = galaxyTxt.getText().toString();
            star = starTxt.getText().toString();

            if (dobTxt.getDate() != null) {
                dob = dobTxt.getFormat().format(dobTxt.getDate());
            } else {
                dobTxt.setError("Invalid Date");
                dobTxt.requestFocus();
                return;
            }

            updateScientist(name, description, galaxy, star, dob);

        }
    }
    private void deleteData() {
        Integer result = scientistViewModel.delete(receivedScientist);
        if (result != null) {
            if (result > 0) {
                Utils.show(this, "DELETE SUCCESSFUL");
            } else {
                Utils.show(this, "DELETE UNSUCCESSFUL");
            }
        } else {
            Utils.show(this, "UNSUCCESSFUL. ERRORED OCCURED");
        }
    }
    private void showSelectedStarInEditText() {
        starTxt.setOnClickListener(v -> Utils.selectStar(c, starTxt));
    }

    @Override
    public void onBackPressed() {
        Utils.showInfoDialog(this, "Warning", "Are you sure you want to exit?");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if (receivedScientist == null) {
            getMenuInflater().inflate(R.menu.new_item_menu, menu);
            headerTxt.setText("Add New Scientist");
        } else {
            getMenuInflater().inflate(R.menu.edit_item_menu, menu);
            headerTxt.setText("Edit Existing Scientist");
        }
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.insertMenuItem:
                insertData();
                return true;
            case R.id.editMenuItem:
                if (receivedScientist != null) {
                    updateData();
                } else {
                    Utils.show(this, "EDIT ONLY WORKS IN EDITING MODE");
                }
                return true;
            case R.id.deleteMenuItem:
                if (receivedScientist != null) {
                    deleteData();
                } else {
                    Utils.show(this, "DELETE ONLY WORKS IN EDITING MODE");
                }
                return true;
            case R.id.viewAllMenuItem:
                Utils.openActivity(this, ScientistsActivity.class);
                finish();
                return true;
            case android.R.id.home:
                NavUtils.navigateUpFromSameTask(this);
                finish();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * Attach Base Context
     */
    @Override
    protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(ViewPumpContextWrapper.wrap(newBase));
    }

    /**
     * When our activity is resumed we will receive our data and set them to their editing
     * widgets.
     */
    @Override
    protected void onResume() {
        super.onResume();
        Scientist o = Utils.receiveScientist(getIntent(), c);
        if (o != null) {
            receivedScientist = o;
            nameTxt.setText(receivedScientist.getName());
            descriptionTxt.setText(receivedScientist.getDescription());
            galaxyTxt.setText(receivedScientist.getGalaxy());
            starTxt.setText(receivedScientist.getStar());
            Object dob = receivedScientist.getDob();
            if (dob != null) {
                dobTxt.setDate(Utils.giveMeDate(dob.toString()));
            }
        } else {
            //Utils.show(c,"Received Scientist is Null");
        }
    }

    /**
     * Let's override our onCreate() method
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_crud);

        scientistViewModel = ViewModelProviders.of(this).get(ScientistViewModel.class);

        this.initializeWidgets();
        this.showSelectedStarInEditText();
    }
}
//end

Demo

Room LiveData CRUD

Room LiveData CRUD