Open In App

How to Build a Simple Note Android App using MVVM and Room Database?

Improve
Improve
Like Article
Like
Save
Share
Report

Android provides us a feature with which we can store users’ data inside their mobile itself with different storage options such as Shared Preferences, SQLite database, and the Room Database. All the data storing techniques are having different use cases. In this article, we will specifically take a look at using a Room Database with Architecture Components in Android. In this article, we will be specifically looking at components such as LiveData, ViewModel, and Room. We can get to see the explanation of each component in detail. Below is the guide for it. 

The components which we will be using inside the application are listed below with a detailed explanation : 

  • LiveData: Live Data is a data holder class that can be observed. It holds as well as caches the latest version of the data and notifies our observer whenever the data is being updated or changed. Live Data automatically manages all of this since it is aware of the relevant lifecycle status changes while observing.
  • ViewModel: View Modal acts as a communication center between repository and UI. The UI no longer needs to worry about the origin of the data. The ViewModel instances survive Activity/Fragment recreation.
  • Repository: Repository is a class that is mainly used to manage multiple sources of data.
  • Entity: Entity is an annotated class that is used to describe a database table when we are working with Room.
  • Room Database: Room Database is an improvised version of SQLite Database. It simplifies the database work and serves as an access point to the underlying SQLite database. The room uses DAO to issue queries to the SQLite database.
  • DAO: DAO is a Data Access Object which is used for mapping SQL queries to functions.

What we are going to build in this article? 

We will be building a simple Notes Application in which we will be displaying the list of notes in Recycler View which is added by the user. Along with that, we will be also able to add a new note to your app. We will be using Room Database for storing data in users’ devices. Below is the video in which we will get to see what we are going to build in this article. Note that we are going to implement this project using the Kotlin language. 

Step by Step Implementation

Step 1: Create a New Project

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Kotlin as the programming language.

Step 2: Updating build.gradle (project) file. 

Navigate to the app > Gradle Scripts > build.gradle(:project) level file and inside this file, we have to add the below code in that file which will be used for our dependencies versions. So we have to add the below block of code in the last of this file. 

ext {
    activityVersion = '1.2.3'
    appCompatVersion = '1.3.0'
    constraintLayoutVersion = '2.0.4'
    coreTestingVersion = '2.1.0'
    coroutines = '1.5.0'
    lifecycleVersion = '2.3.1'
    materialVersion = '1.3.0'
    roomVersion = '2.3.0'
    // testing
    junitVersion = '4.13.2'
    espressoVersion = '3.1.0'
    androidxJunitVersion = '1.1.2'
}  

Step 3: Updating your build.gradle (:app) file

Navigate to the app > build.gradle and inside that, in the first plugins section, we have to add id for one more plugin. Below is the code for all the plugins which are present inside our build.gradle.

plugins {
    id 'com.android.application'
    id 'kotlin-android'
    // add below plugin
    id 'kotlin-kapt'
}

Now inside the android section in the same file, we have to add the below block at the last part in the android section. Below is the code for that block. 

packagingOptions {
    exclude 'META-INF/atomicfu.kotlin_module'
}

Now add the below dependencies inside your build.gradle file. We have to simply update the dependencies section with the below one. 

dependencies {
    implementation "androidx.appcompat:appcompat:$rootProject.appCompatVersion"
    implementation "androidx.activity:activity-ktx:$rootProject.activityVersion"

    // Dependencies for working with Architecture components
    // You'll probably have to update the version numbers in build.gradle (Project)

    // Room components
    implementation "androidx.room:room-ktx:$rootProject.roomVersion"
    kapt "androidx.room:room-compiler:$rootProject.roomVersion"
    androidTestImplementation "androidx.room:room-testing:$rootProject.roomVersion"

    // Lifecycle components
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.lifecycleVersion"
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:$rootProject.lifecycleVersion"
    implementation "androidx.lifecycle:lifecycle-common-java8:$rootProject.lifecycleVersion"

    // Kotlin components
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutines"
    api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines"

    // UI
    implementation "androidx.constraintlayout:constraintlayout:$rootProject.constraintLayoutVersion"
    implementation "com.google.android.material:material:$rootProject.materialVersion"

    // Testing
    testImplementation "junit:junit:$rootProject.junitVersion"
    androidTestImplementation "androidx.arch.core:core-testing:$rootProject.coreTestingVersion"
    androidTestImplementation ("androidx.test.espresso:espresso-core:$rootProject.espressoVersion", {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    androidTestImplementation "androidx.test.ext:junit:$rootProject.androidxJunitVersion"
}

After updating your gradle file. Now we have to sync your project and then we have to install all the dependencies inside the application by clicking on the sync now option at the top right corner. After installing all the dependencies inside our application we will now be moving to create an Entity for our application. 

Step 4: Adding new colors in the colors.xml file

Navigate to the app > res > values > colors.xml and add below colors to it. 

XML




<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="purple_200">#296D98</color>
    <color name="purple_500">#296D98</color>
    <color name="purple_700">#296D98</color>
    <color name="teal_200">#FF03DAC5</color>
    <color name="teal_700">#FF018786</color>
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>
 
    <color name="black_shade_1">#0e2433</color>
    <color name="black_shade_2">#1C4966</color>
    <color name="black_shade_3">#22252D</color>
    <color name="gray">#424242</color>
    <color name="yellow">#ffa500</color>
    <color name="dark_blue_shade">#0D2162</color>
    <color name="dark_blue_shade_2">#17388E</color>
    <color name="light_blue_shade">#12B2E6</color>
 
</resources>


Step 5: Creating an Entity

An Entity is basically a modal class or a structure of our database in which we will be used for creating a database structure. Inside our app, we will be having a simple table that will be only having two columns such as ID and a text. ID will be used for the identification of an entry and text is the column for the identification of text column. Below is the table structure for our database. Below is the image for the database. 

For creating a new Entity, we have to create a new Kotlin class. For creating this we simply have to navigate to your app’s package name. Right-click on it then new and select Kotlin File/Class and then specify the Class name as Note and add the below code to it. Comments are added in the code to get to know in more detail. 

Kotlin




package com.gtappdevelopers.noteapplication
 
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
 
// on below line we are specifying our table name
@Entity(tableName = "notesTable")
 
// on below line we are specifying our column info
// and inside that we are passing our column name
class Note (@ColumnInfo(name = "title")val noteTitle :String,@ColumnInfo(name = "description")val noteDescription :String,@ColumnInfo(name = "timestamp")val timeStamp :String) {
    // on below line we are specifying our key and
    // then auto generate as true and we are
    // specifying its initial value as 0
    @PrimaryKey(autoGenerate = true) var id = 0
}


 
Step 6: Creating a DAO class

DAO is a data access object which is used to specify SQL queries and then associate them with different method calls. DAO may be an abstract class or an interface. Inside the DAO class, we have to create different methods such as inserting, deleting the data, and reading the data from our database. So this class will basically interact with our database to add or delete data inside our database.

For creating a DAO interface we simply have to navigate to the app’s package name, Right-click on it > New Kotlin File and we have to select as Interface and name it as NotesDao and we have to create this file. After creating this file we have to add the below code to it. 

Kotlin




package com.gtappdevelopers.noteapplication
 
import androidx.lifecycle.LiveData
import androidx.room.*
 
// annotation for dao class.
@Dao
interface NotesDao {
 
    // below is the insert method for
    // adding a new entry to our database.
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insert(note :Note)
 
    // below is the delete method
    // for deleting our note.
    @Delete
    suspend fun delete(note: Note)
 
    // below is the method to read all the notes
    // from our database we have specified the query for it.
    // inside the query we are arranging it in ascending
    // order on below line and we are specifying
    // the table name from which
    // we have to get the data.
    @Query("Select * from notesTable order by id ASC")
    fun getAllNotes(): LiveData<List<Note>>
   
      // below method is use to update the note.
      @Update
    suspend fun update(note: Note)
 
}


 
Step 7: Adding a Room Database for our application

What is basically a Room Database?

  • Room is basically a database layer on top of the SQLite database.
  • Room takes care of mundane tasks that you used to handle with an SQLite Open Helper.
  • Room uses the DAO to issue queries to its database.
  • Room provides compile-time checks of SQLite statements.

Now to store data inside the user’s device we have to create a Room database for storing the data. So for creating a database, we have to create an abstract class for creating our database. In this, we will be simply building our database using Room and we will be specifying our database name. For creating a new abstract class we have to go to the app’s package name > Right-click on it > New > Kotlin file and we name it as NoteDatabase. After creating this class we have to add the below code to it. Comments are added in the code to get to know in more detail. 

Kotlin




package com.gtappdevelopers.noteapplication
 
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
 
@Database(entities = arrayOf(Note::class), version = 1, exportSchema = false)
abstract class NoteDatabase : RoomDatabase() {
 
    abstract fun getNotesDao(): NotesDao
 
    companion object {
        // Singleton prevents multiple
        // instances of database opening at the
        // same time.
        @Volatile
        private var INSTANCE: NoteDatabase? = null
 
        fun getDatabase(context: Context): NoteDatabase {
            // if the INSTANCE is not null, then return it,
            // if it is, then create the database
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    NoteDatabase::class.java,
                    "note_database"
                ).build()
                INSTANCE = instance
                // return instance
                instance
            }
        }
    }
}


 
Step 8: Creating a Repository Class

Repository class basically abstracts the access to multiple data sources such as getting the data from API or getting the data from Room database. A repository class will provides us a clean API for data access for the rest of the application. The repository will contain a logic that will be deciding whether we have to fetch the data from the network or we have to get the data from Database. 

Creating a Repository Class. For creating a Repository we have to create a new Kotlin file by simply right-clicking on your app’s package name > Right-click on it > New > Kotlin class and specify the class name as NoteRepository and add below code to it. Comments are added in the code to get to know in more detail. 

Kotlin




package com.gtappdevelopers.noteapplication
 
import androidx.annotation.WorkerThread
import androidx.lifecycle.LiveData
import java.util.concurrent.Flow
 
class NoteRepository(private val notesDao: NotesDao) {
     
    // on below line we are creating a variable for our list
    // and we are getting all the notes from our DAO class.
    val allNotes: LiveData<List<Note>> = notesDao.getAllNotes()
     
    // on below line we are creating an insert method
    // for adding the note to our database.
    suspend fun insert(note: Note) {
        notesDao.insert(note)
    }
     
    // on below line we are creating a delete method
    // for deleting our note from database.
    suspend fun delete(note: Note){
        notesDao.delete(note)
    }
     
     // on below line we are creating a update method for
     // updating our note from database.
     suspend fun update(note: Note){
        notesDao.update(note)
    }
}


 
Step 9: Creating a ViewModel 

ViewModel is basically used for providing the data to our User Interface. It acts as a communication layer between Repository and the UI. We can use View Modal to share data between our fragments. For creating a View Modal we have to simply create a new Kotlin class and then we have to name it as NoteViewModal and add the below code to it. Comments are added in the code to get to know in more detail. 

Kotlin




package com.gtappdevelopers.noteapplication
 
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
 
class NoteViewModal (application: Application) :AndroidViewModel(application) {
     
    // on below line we are creating a variable
    // for our all notes list and repository
    val allNotes : LiveData<List<Note>>
    val repository : NoteRepository
 
    // on below line we are initializing
    // our dao, repository and all notes
    init {
        val dao = NoteDatabase.getDatabase(application).getNotesDao()
        repository = NoteRepository(dao)
        allNotes = repository.allNotes
    }
 
    // on below line we are creating a new method for deleting a note. In this we are
    // calling a delete method from our repository to delete our note.
    fun deleteNote (note: Note) = viewModelScope.launch(Dispatchers.IO) {
        repository.delete(note)
    }
     
    // on below line we are creating a new method for updating a note. In this we are
    // calling a update method from our repository to update our note.
    fun updateNote(note: Note) = viewModelScope.launch(Dispatchers.IO) {
       repository.update(note)
    }
 
         
    // on below line we are creating a new method for adding a new note to our database
    // we are calling a method from our repository to add a new note.
    fun addNote(note: Note) = viewModelScope.launch(Dispatchers.IO) {
        repository.insert(note)
    }
}


 
Step 10: Working with the activity_main.xml file 

Now we will be working on the UI part of our application. Now we have to navigate to app > res > activity_main.xml and add the below code to it. Comments are added in the code to get to know in more detail.

XML




<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black_shade_1"
    tools:context=".MainActivity">
 
    <!--recycler view for displaying all notes-->
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/notesRV"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="5dp"
        tools:listitem="@layout/note_rv_item" />
 
    <!--fab for adding a new note-->
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/idFAB"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:layout_margin="20dp"
        android:src="@drawable/ic_add"
        app:backgroundTint="@color/black_shade_2"
        app:tint="@color/white" />
 
</RelativeLayout>


Step 11: Creating a new layout file for our item of RecyclerView 

Navigate to the app > res > layout > Right-click on it > New > Layout Resource file and name your file as note_rv_item and add the below code to it. Comments are added in the code to get to know in more detail. 

XML




<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    app:cardBackgroundColor="@color/black_shade_2"
    app:cardCornerRadius="5dp"
    app:cardElevation="3dp">
 
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="4dp">
 
        <!--text view for displaying our note text-->
        <TextView
            android:id="@+id/idTVNote"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="3dp"
            android:layout_toLeftOf="@id/idIVDelete"
            android:padding="4dp"
            android:text="Note"
            android:textColor="@color/white"
            android:textSize="18sp" />
 
        <!--text view for displaying our last updated text-->
        <TextView
            android:id="@+id/idTVDate"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/idTVNote"
            android:layout_margin="3dp"
            android:layout_toLeftOf="@id/idIVDelete"
            android:padding="4dp"
            android:text="Updated At"
            android:textColor="@color/white"
            android:textSize="13sp" />
 
        <!--imageview for displaying delete icon-->
        <ImageView
            android:id="@+id/idIVDelete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_margin="3dp"
            android:padding="3dp"
            android:src="@drawable/ic_delete"
            app:tint="@color/white" />
 
    </RelativeLayout>
     
</androidx.cardview.widget.CardView>


Step 12: Creating an Adapter class

Now we will be creating an adapter class that will be used for setting the data to each item of our recycler view. For creating an Adapter class, we have to navigate to the app > java > your app’s package name > Right-click on it > New > Kotlin/Class and name it as NoteRVAdapter and add the below code to it. Comments are added in the code to get to know in more detail. 

Kotlin




package com.gtappdevelopers.noteapplication
 
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
 
class NoteRVAdapter(
    val context: Context,
    val noteClickDeleteInterface: NoteClickDeleteInterface,
    val noteClickInterface: NoteClickInterface
) :
    RecyclerView.Adapter<NoteRVAdapter.ViewHolder>() {
 
    // on below line we are creating a
    // variable for our all notes list.
    private val allNotes = ArrayList<Note>()
 
    // on below line we are creating a view holder class.
    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        // on below line we are creating an initializing all our
        // variables which we have added in layout file.
        val noteTV = itemView.findViewById<TextView>(R.id.idTVNote)
        val dateTV = itemView.findViewById<TextView>(R.id.idTVDate)
        val deleteIV = itemView.findViewById<ImageView>(R.id.idIVDelete)
    }
 
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        // inflating our layout file for each item of recycler view.
        val itemView = LayoutInflater.from(parent.context).inflate(
            R.layout.note_rv_item,
            parent, false
        )
        return ViewHolder(itemView)
    }
 
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        // on below line we are setting data to item of recycler view.
        holder.noteTV.setText(allNotes.get(position).noteTitle)
        holder.dateTV.setText("Last Updated : " + allNotes.get(position).timeStamp)
        // on below line we are adding click listener to our delete image view icon.
        holder.deleteIV.setOnClickListener {
            // on below line we are calling a note click
            // interface and we are passing a position to it.
            noteClickDeleteInterface.onDeleteIconClick(allNotes.get(position))
        }
 
        // on below line we are adding click listener
        // to our recycler view item.
        holder.itemView.setOnClickListener {
            // on below line we are calling a note click interface
            // and we are passing a position to it.
            noteClickInterface.onNoteClick(allNotes.get(position))
        }
    }
 
    override fun getItemCount(): Int {
        // on below line we are
        // returning our list size.
        return allNotes.size
    }
 
    // below method is use to update our list of notes.
    fun updateList(newList: List<Note>) {
        // on below line we are clearing
        // our notes array list
        allNotes.clear()
        // on below line we are adding a
        // new list to our all notes list.
        allNotes.addAll(newList)
        // on below line we are calling notify data
        // change method to notify our adapter.
        notifyDataSetChanged()
    }
}
 
interface NoteClickDeleteInterface {
    // creating a method for click
    // action on delete image view.
    fun onDeleteIconClick(note: Note)
}
 
interface NoteClickInterface {
    // creating a method for click action
    // on recycler view item for updating it.
    fun onNoteClick(note: Note)
}


 
Step 13: Creating a new Activity for adding as well as Editing a note 

Navigate to the app > java > your app’s package name > Right-click on it > New > select Empty Activity and name it as AddEditNoteActivity and create a new activity. After that navigate to the app > res > layout > activity_add_edit_note.xml file and add the below code to it. Comments are added in the code to get to know in more detail.

XML




<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black_shade_1"
    tools:context=".AddEditNoteActivity">
 
    <!--edit text for note title-->
    <EditText
        android:id="@+id/idEdtNoteName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:hint="Enter Note Title"
        android:textColor="@color/white"
        android:textColorHint="@color/white" />
     
    <!--edit text for note description-->
    <EditText
        android:id="@+id/idEdtNoteDesc"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/idBtn"
        android:layout_below="@id/idEdtNoteName"
        android:layout_margin="10dp"
        android:background="@color/black_shade_1"
        android:gravity="start|top"
        android:hint="Enter your Note Details"
        android:inputType="textMultiLine"
        android:singleLine="false"
        android:textColor="@color/white"
        android:textColorHint="@color/white" />
 
    <!--button for saving and updating a note-->
    <Button
        android:id="@+id/idBtn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_margin="20dp"
        android:background="@drawable/custom_button_back"
        android:text="Button"
        android:textAllCaps="false"
        android:textColor="@color/white" />
 
</RelativeLayout>


 
Step 14: Working with MainActivity.kt file

Navigate to the app > java > your app’s package name > MainActivity.kt file and add the below code to it. Comments are added in the code to get to know in more detail. 

Kotlin




package com.gtappdevelopers.noteapplication
 
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.floatingactionbutton.FloatingActionButton
import java.util.*
 
class MainActivity : AppCompatActivity(), NoteClickInterface, NoteClickDeleteInterface {
 
    // on below line we are creating a variable
    // for our recycler view, exit text, button and viewmodel.
    lateinit var viewModal: NoteViewModal
    lateinit var notesRV: RecyclerView
    lateinit var addFAB: FloatingActionButton
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
         
        // on below line we are initializing
        // all our variables.
        notesRV = findViewById(R.id.notesRV)
        addFAB = findViewById(R.id.idFAB)
         
        // on below line we are setting layout
        // manager to our recycler view.
        notesRV.layoutManager = LinearLayoutManager(this)
         
        // on below line we are initializing our adapter class.
        val noteRVAdapter = NoteRVAdapter(this, this, this)
         
        // on below line we are setting
        // adapter to our recycler view.
        notesRV.adapter = noteRVAdapter
         
        // on below line we are
        // initializing our view modal.
        viewModal = ViewModelProvider(
            this,
            ViewModelProvider.AndroidViewModelFactory.getInstance(application)
        ).get(NoteViewModal::class.java)
         
        // on below line we are calling all notes method
        // from our view modal class to observer the changes on list.
        viewModal.allNotes.observe(this, Observer { list ->
            list?.let {
                // on below line we are updating our list.
                noteRVAdapter.updateList(it)
            }
        })
        addFAB.setOnClickListener {
            // adding a click listener for fab button
            // and opening a new intent to add a new note.
            val intent = Intent(this@MainActivity, AddEditNoteActivity::class.java)
            startActivity(intent)
            this.finish()
        }
    }
 
    override fun onNoteClick(note: Note) {
        // opening a new intent and passing a data to it.
        val intent = Intent(this@MainActivity, AddEditNoteActivity::class.java)
        intent.putExtra("noteType", "Edit")
        intent.putExtra("noteTitle", note.noteTitle)
        intent.putExtra("noteDescription", note.noteDescription)
        intent.putExtra("noteId", note.id)
        startActivity(intent)
        this.finish()
    }
 
    override fun onDeleteIconClick(note: Note) {
        // in on note click method we are calling delete
        // method from our view modal to delete our not.
        viewModal.deleteNote(note)
        // displaying a toast message
        Toast.makeText(this, "${note.noteTitle} Deleted", Toast.LENGTH_LONG).show()
    }
}


Step 15: Working with the AddEditNoteActivity.kt file

Navigate to the app > java > your app’s package name > AddEditNoteActivity.java and add the below code to it. Comments are added in the code to get to know in more detail. 

Kotlin




package com.gtappdevelopers.noteapplication
 
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import java.text.SimpleDateFormat
import java.util.*
 
class AddEditNoteActivity : AppCompatActivity() {
    // on below line we are creating
    // variables for our UI components.
    lateinit var noteTitleEdt: EditText
    lateinit var noteEdt: EditText
    lateinit var saveBtn: Button
 
    // on below line we are creating variable for
    // viewmodal and integer for our note id.
    lateinit var viewModal: NoteViewModal
    var noteID = -1;
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_add_edit_note)
         
        // on below line we are initializing our view modal.
        viewModal = ViewModelProvider(
            this,
            ViewModelProvider.AndroidViewModelFactory.getInstance(application)
        ).get(NoteViewModal::class.java)
         
        // on below line we are initializing all our variables.
        noteTitleEdt = findViewById(R.id.idEdtNoteName)
        noteEdt = findViewById(R.id.idEdtNoteDesc)
        saveBtn = findViewById(R.id.idBtn)
 
        // on below line we are getting data passed via an intent.
        val noteType = intent.getStringExtra("noteType")
        if (noteType.equals("Edit")) {
            // on below line we are setting data to edit text.
            val noteTitle = intent.getStringExtra("noteTitle")
            val noteDescription = intent.getStringExtra("noteDescription")
            noteID = intent.getIntExtra("noteId", -1)
            saveBtn.setText("Update Note")
            noteTitleEdt.setText(noteTitle)
            noteEdt.setText(noteDescription)
        } else {
            saveBtn.setText("Save Note")
        }
 
        // on below line we are adding
        // click listener to our save button.
        saveBtn.setOnClickListener {
            // on below line we are getting
            // title and desc from edit text.
            val noteTitle = noteTitleEdt.text.toString()
            val noteDescription = noteEdt.text.toString()
            // on below line we are checking the type
            // and then saving or updating the data.
            if (noteType.equals("Edit")) {
                if (noteTitle.isNotEmpty() && noteDescription.isNotEmpty()) {
                    val sdf = SimpleDateFormat("dd MMM, yyyy - HH:mm")
                    val currentDateAndTime: String = sdf.format(Date())
                    val updatedNote = Note(noteTitle, noteDescription, currentDateAndTime)
                    updatedNote.id = noteID
                    viewModal.updateNote(updatedNote)
                    Toast.makeText(this, "Note Updated..", Toast.LENGTH_LONG).show()
                }
            } else {
                if (noteTitle.isNotEmpty() && noteDescription.isNotEmpty()) {
                    val sdf = SimpleDateFormat("dd MMM, yyyy - HH:mm")
                    val currentDateAndTime: String = sdf.format(Date())
                    // if the string is not empty we are calling a
                    // add note method to add data to our room database.
                    viewModal.addNote(Note(noteTitle, noteDescription, currentDateAndTime))
                    Toast.makeText(this, "$noteTitle Added", Toast.LENGTH_LONG).show()
                }
            }
            // opening the new activity on below line
            startActivity(Intent(applicationContext, MainActivity::class.java))
            this.finish()
        }
    }
}


 
Now run your application to see the output of the application.

 Output:

Get the complete project from here.

 



Last Updated : 23 Jan, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads