Site icon C1CTech

Android Room Database with MVVM Architecture

&NewLine;<p>This post is about how to use Room Database with MVVM Architecture with the help of a simple application&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<div class&equals;"wp-block-buttons is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-a89b3969 wp-block-buttons-is-layout-flex"> &NewLine;<div class&equals;"wp-block-button"><a class&equals;"wp-block-button&lowbar;&lowbar;link has-white-color has-text-color has-background" style&equals;"background-color&colon; &num;250376&semi;" href&equals;"https&colon;&sol;&sol;github&period;com&sol;arunk7839&sol;MVVMWithRoomDB"><strong>DOWNLOAD CODE<&sol;strong><&sol;a><&sol;div> &NewLine;<&sol;div> &NewLine; &NewLine; &NewLine; &NewLine;<p>&nbsp&semi;<&sol;p> &NewLine;<p><amp-youtube layout&equals;"responsive" width&equals;"1200" height&equals;"675" data-videoid&equals;"hOPnXSAyVPg" title&equals;"Android Room Database with MVVM Architecture"><a placeholder href&equals;"https&colon;&sol;&sol;youtu&period;be&sol;hOPnXSAyVPg"><img src&equals;"https&colon;&sol;&sol;i&period;ytimg&period;com&sol;vi&sol;hOPnXSAyVPg&sol;hqdefault&period;jpg" layout&equals;"fill" object-fit&equals;"cover" alt&equals;"Android Room Database with MVVM Architecture"><&sol;a><&sol;amp-youtube><&sol;p> &NewLine;<h4> <&sol;h4> &NewLine;<h4><span style&equals;"color&colon; &num;000080&semi;"><strong>What is MVVM&quest;<&sol;strong><&sol;span><&sol;h4> &NewLine;<ul> &NewLine;<li>MVVM architecture is a <span style&equals;"color&colon; &num;008000&semi;"><strong>Model-View-ViewModel <&sol;strong><&sol;span>architecture&period;<&sol;li> &NewLine;<li>It allows separating the user interface logic from the business &lpar;or the back-end&rpar; logic&period;<&sol;li> &NewLine;<li>Its target is to keep UI code simple and free of app logic in order to make it easier to manage and test&period; <&sol;li> &NewLine;<&sol;ul> &NewLine;<p>MVVM has mainly the following layers&colon;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>Model<&sol;strong>&colon;<&sol;span><&sol;p> &NewLine;<p>The model represents the data and the business logic of the Application&period; It consists of the business logic – local and remote data source&comma; model classes&comma; repository&period;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>View<&sol;strong>&colon;<&sol;span><&sol;p> &NewLine;<p>The view consists of the UI Code&lpar;Activity&comma; Fragment&rpar;&comma; XML&period; The view role in this pattern is to observe &lpar;or subscribe to&rpar; a ViewModel observable to get data in order to update UI elements accordingly&period;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>ViewModel<&sol;strong><&sol;span>&colon; <&sol;p> &NewLine;<p>The ViewModel is a class whose role is to provide data to the UI and survive configuration changes&period; A ViewModel acts as a communication center between the Repository and the UI&period;<br &sol;>One of the important implementation strategies of this layer is to decouple it from the View&comma; i&period;e&comma; ViewModel should not be aware of the view who is interacting with&period;<&sol;p> &NewLine;<h4><strong><span style&equals;"color&colon; &num;000080&semi;">Room Database<&sol;span><&sol;strong><&sol;h4> &NewLine;<p>The Room persistence library provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite&period; In particular&comma; Room provides the following benefits&colon;<&sol;p> &NewLine;<ul> &NewLine;<li>Compile-time verification of SQL queries&period;<&sol;li> &NewLine;<li>Convenience annotations that minimize repetitive and error-prone boilerplate code&period;<&sol;li> &NewLine;<li>Streamlined database migration paths&period;<&sol;li> &NewLine;<&sol;ul> &NewLine;<h4><span style&equals;"color&colon; &num;000080&semi;"><strong>Creating new project<&sol;strong><&sol;span><&sol;h4> &NewLine;<p>1 &period; Create a new project by going to <span style&equals;"color&colon; &num;008000&semi;"><strong>File &Implies; New Android Project<&sol;strong><&sol;span>&comma; select <span style&equals;"color&colon; &num;008000&semi;"><strong>Empty<&sol;strong><&sol;span> Activity&comma; provide <span style&equals;"color&colon; &num;008000&semi;"><strong>app<&sol;strong><&sol;span> name&comma; select language to <span style&equals;"color&colon; &num;008000&semi;"><strong>kotlin<&sol;strong><&sol;span> and then finally click on <span style&equals;"color&colon; &num;008000&semi;"><strong>finish<&sol;strong><&sol;span>&period;<&sol;p> &NewLine;<p>2 &period; Open app-level build&period;gradle file and add the below changes&colon;<&sol;p> &NewLine;<ul> &NewLine;<li>Add the below libraries under the <span style&equals;"color&colon; &num;008000&semi;"><strong>dependencies<&sol;strong><&sol;span> section<strong>&colon;<&sol;strong><&sol;li> &NewLine;<&sol;ul> &NewLine;<pre>dependencies &lbrace;<br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol;room library<&sol;span><&sol;strong><br &sol;> implementation 'androidx&period;room&colon;room-runtime&colon;2&period;4&period;1'<br &sol;> kapt 'androidx&period;room&colon;room-compiler&colon;2&period;4&period;1'<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; Kotlin Extensions and Coroutines support for Room<&sol;span><&sol;strong><br &sol;> implementation "androidx&period;room&colon;room-ktx&colon;2&period;4&period;1"<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol;ViewModel and livedata<&sol;span><&sol;strong><br &sol;> implementation "androidx&period;lifecycle&colon;lifecycle-viewmodel-ktx&colon;2&period;2&period;0"<br &sol;> implementation "androidx&period;lifecycle&colon;lifecycle-livedata-ktx&colon;2&period;2&period;0"<br &sol;> implementation "androidx&period;lifecycle&colon;lifecycle-common-java8&colon;2&period;2&period;0"<br &sol;>&rcub;<&sol;pre> &NewLine;<ul> &NewLine;<li>Inside the <span style&equals;"color&colon; &num;008000&semi;"><strong>android<&sol;strong><&sol;span> block&comma; add <strong><span style&equals;"color&colon; &num;008000&semi;">buildFeatures<&sol;span><&sol;strong> block with property <strong><span style&equals;"color&colon; &num;0000ff&semi;">viewBinding<&sol;span><&sol;strong> to <span style&equals;"color&colon; &num;0000ff&semi;"><strong>true<&sol;strong><&sol;span>&period;<&sol;li> &NewLine;<&sol;ul> &NewLine;<pre>buildFeatures &lbrace;<br &sol;> viewBinding true<br &sol;>&rcub;<&sol;pre> &NewLine;<ul> &NewLine;<li>Inside <span style&equals;"color&colon; &num;008000&semi;"><strong>plugins<&sol;strong><&sol;span> block&comma; add the below plugin&colon;<&sol;li> &NewLine;<&sol;ul> &NewLine;<pre>plugins &lbrace;<br &sol;> id 'com&period;android&period;application'<br &sol;> id 'kotlin-android'<br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> id 'kotlin-kapt'<&sol;span><&sol;strong><br &sol;>&rcub;<&sol;pre> &NewLine;<ul> &NewLine;<li>Finally&comma; click on <strong><span style&equals;"color&colon; &num;008000&semi;">Sync Now<&sol;span>&period;<&sol;strong><&sol;li> &NewLine;<&sol;ul> &NewLine;<h4><span style&equals;"color&colon; &num;000080&semi;"><strong>Creating Room components &lpar;Entity&comma; Dao and Database&rpar;<&sol;strong><&sol;span><&sol;h4> &NewLine;<h5><strong><span style&equals;"color&colon; &num;0000ff&semi;">Entity&colon;<&sol;span><&sol;strong><&sol;h5> &NewLine;<p>Entity is an annotated class that is used to describe a database table when we are working with Room&period;<&sol;p> &NewLine;<h5><strong><span style&equals;"color&colon; &num;0000ff&semi;">Database<&sol;span><&sol;strong>&colon;<&sol;h5> &NewLine;<p>Database serves as the app&&num;8217&semi;s main access point to the underlying SQLite database&period; It uses DAO to issue queries to the SQLite database&period;<&sol;p> &NewLine;<h5><strong><span style&equals;"color&colon; &num;0000ff&semi;">DAO&colon;<&sol;span> <&sol;strong><&sol;h5> &NewLine;<p>DAO is a Data Access Object which is used for mapping SQL queries to functions&period;<&sol;p> &NewLine;<h5><br &sol;><span style&equals;"color&colon; &num;000080&semi;"><strong>Creating an Entity<&sol;strong><&sol;span><&sol;h5> &NewLine;<p>The following code defines an <span style&equals;"color&colon; &num;008000&semi;"><strong>Event<&sol;strong><&sol;span> entity&period; Each instance of Event represents a row in an <strong><span style&equals;"color&colon; &num;008000&semi;">eventTable<&sol;span><&sol;strong> in the app&&num;8217&semi;s database&period; Each row represents one entity &lpar;or record&rpar;&comma; and each column represents a value in that entity&period; <&sol;p> &NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Event&period;kt<&sol;span><&sol;strong><&sol;p> &NewLine;<pre>&commat;Entity&lpar;tableName &equals; "eventTable"&rpar;<br &sol;>data class Event&lpar;<br &sol;> &commat;PrimaryKey&lpar;autoGenerate &equals; true&rpar;<br &sol;> &commat;ColumnInfo&lpar;name &equals; "event&lowbar;id"&rpar;<br &sol;> val id&colon; Int&quest;&comma;<br &sol;><br &sol;> &commat;ColumnInfo&lpar;name &equals; "event&lowbar;title"&rpar;<br &sol;> val title&colon; String&quest;&comma;<br &sol;><br &sol;> &commat;ColumnInfo&lpar;name &equals; "event&lowbar;description"&rpar;<br &sol;> val description&colon; String&quest;<br &sol;>&rpar;<&sol;pre> &NewLine;<h5><br &sol;><span style&equals;"color&colon; &num;000080&semi;"><strong>Creating a DAO&lpar;Data access object&rpar; class<&sol;strong><&sol;span><&sol;h5> &NewLine;<p>The following code defines a DAO called <span style&equals;"color&colon; &num;008000&semi;"><strong>EventsDao<&sol;strong><&sol;span>&period; EventsDao provides the methods that the rest of the app uses to interact with data in the <strong><span style&equals;"color&colon; &num;008000&semi;">eventTable<&sol;span><&sol;strong>&period;<&sol;p> &NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">EventsDao&period;kt<&sol;span><&sol;strong><&sol;p> &NewLine;<pre>&commat;Dao<br &sol;>interface EventsDao &lbrace;<br &sol;> <strong><span style&equals;"color&colon; &num;008000&semi;">&sol;&sol; adds a new entry to our database&period;<&sol;span><&sol;strong><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; if some data is same&sol;conflict&comma; it'll be replace with new data<&sol;span><&sol;strong><br &sol;> &commat;Insert&lpar;onConflict &equals; OnConflictStrategy&period;REPLACE&rpar;<br &sol;> suspend fun insertEvent&lpar;event &colon;Event&rpar;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; deletes an event<&sol;span><&sol;strong><br &sol;> &commat;Delete<br &sol;> suspend fun deleteEvent&lpar;event&colon; Event&rpar;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; updates an event&period;<&sol;span><&sol;strong><br &sol;> &commat;Update<br &sol;> suspend fun updateEvent&lpar;event&colon; Event&rpar;<br &sol;><br &sol;> <span style&equals;"color&colon; &num;008000&semi;"><strong>&sol;&sol; read all the events from eventTable<&sol;strong><&sol;span><br &sol;><span style&equals;"color&colon; &num;008000&semi;"><strong> &sol;&sol; and arrange events in ascending order<&sol;strong><&sol;span><br &sol;><span style&equals;"color&colon; &num;008000&semi;"><strong> &sol;&sol; of their ids<&sol;strong><&sol;span><br &sol;> &commat;Query&lpar;"Select &ast; from eventTable order by event&lowbar;id ASC"&rpar;<br &sol;> fun getAllEvents&lpar;&rpar;&colon; LiveData&lt&semi;List&lt&semi;Event&gt&semi;&gt&semi;<br &sol;> <strong><span style&equals;"color&colon; &num;008000&semi;">&sol;&sol; why not use suspend &quest; because Room does not support LiveData with suspended functions&period;<&sol;span><&sol;strong><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; LiveData already works on a background thread and should be used directly without using coroutines<&sol;span><&sol;strong><br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; delete all events<&sol;span><&sol;strong><br &sol;> &commat;Query&lpar;"DELETE FROM eventTable"&rpar;<br &sol;> suspend fun clearEvent&lpar;&rpar;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol;you can use this too&comma; to delete an event by id&period;<&sol;span><&sol;strong><br &sol;> &commat;Query&lpar;"DELETE FROM eventTable WHERE event&lowbar;id &equals; &colon;id"&rpar;<br &sol;> suspend fun deleteEventById&lpar;id&colon; Int&rpar;<br &sol;>&rcub;<&sol;pre> &NewLine;<h5><br &sol;><span style&equals;"color&colon; &num;000080&semi;"><strong>Creating Database class<&sol;strong><&sol;span><&sol;h5> &NewLine;<p>The following code defines an <strong><span style&equals;"color&colon; &num;008000&semi;">EventDatabase<&sol;span><&sol;strong> class to hold the database&period; EventDatabase defines the database configuration and serves as the app&&num;8217&semi;s main access point to the persisted data&period;<&sol;p> &NewLine;<p>The database class must satisfy the following conditions&colon;<&sol;p> &NewLine;<ul> &NewLine;<li>must be annotated with a <strong><span style&equals;"color&colon; &num;008000&semi;">&commat;Database<&sol;span><&sol;strong> annotation that includes an entities array&period;<&sol;li> &NewLine;<li>must be an <strong><span style&equals;"color&colon; &num;008000&semi;">abstract<&sol;span><&sol;strong> class that extends <strong><span style&equals;"color&colon; &num;008000&semi;">RoomDatabase<&sol;span><&sol;strong>&period;<&sol;li> &NewLine;<li>for each DAO class that is associated with the database&comma; the database class must define an abstract method that has zero arguments and returns an instance of the DAO class&period;<&sol;li> &NewLine;<&sol;ul> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>EventDatabase&period;kt<&sol;strong><&sol;span><&sol;p> &NewLine;<pre>&commat;Database&lpar;entities &equals; &lbrack;Event&colon;&colon;class&rsqb;&comma; version &equals; 1&comma; exportSchema &equals; false&rpar;<br &sol;>abstract class EventDatabase &colon; RoomDatabase&lpar;&rpar; &lbrace;<br &sol;><br &sol;> abstract fun getEventsDao&lpar;&rpar;&colon; EventsDao<br &sol;><br &sol;> companion object &lbrace;<br &sol;> <strong><span style&equals;"color&colon; &num;008000&semi;">&sol;&sol; Volatile annotation means any change to this field<&sol;span><&sol;strong><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; are immediately visible to other threads&period;<&sol;span><&sol;strong><br &sol;> &commat;Volatile<br &sol;> private var INSTANCE&colon; EventDatabase&quest; &equals; null<br &sol;><br &sol;> private const val DB&lowbar;NAME &equals; "event&lowbar;database&period;db"<br &sol;><br &sol;> fun getDatabase&lpar;context&colon; Context&rpar;&colon; EventDatabase &lbrace;<br &sol;> <strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; if the INSTANCE is not null&comma; then return it&comma;<&sol;span><&sol;strong><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; if it is&comma; then create the database<&sol;span><&sol;strong><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; here synchronised used for blocking the other thread<&sol;span><&sol;strong><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; from accessing another while in a specific code execution&period;<&sol;span><&sol;strong><br &sol;> return INSTANCE &quest;&colon; synchronized&lpar;this&rpar; &lbrace;<br &sol;> val instance &equals; Room&period;databaseBuilder&lpar;<br &sol;> context&period;applicationContext&comma;<br &sol;> EventDatabase&colon;&colon;class&period;java&comma;<br &sol;> DB&lowbar;NAME<br &sol;> &rpar;&period;build&lpar;&rpar;<br &sol;> INSTANCE &equals; instance<br &sol;><span style&equals;"color&colon; &num;008000&semi;"><strong> &sol;&sol; return instance<&sol;strong><&sol;span><br &sol;> instance<br &sol;> &rcub;<br &sol;> &rcub;<br &sol;> &rcub;<br &sol;>&rcub;<&sol;pre> &NewLine;<h5><span style&equals;"color&colon; &num;000080&semi;"><strong>Setup Data Repository<&sol;strong><&sol;span><&sol;h5> &NewLine;<p>A Repository is a class that abstracts access to multiple data sources&period; <&sol;p> &NewLine;<p>The below Repository class contains some methods which invoke the methods of the Dao class&period;<&sol;p> &NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">EventRepositoryt&period;kt<&sol;span><&sol;strong><&sol;p> &NewLine;<pre>import androidx&period;lifecycle&period;LiveData<br &sol;>import com&period;c1ctech&period;mvvmwithroomdb&period;data&period;db&period;EventsDao<br &sol;>import com&period;c1ctech&period;mvvmwithroomdb&period;data&period;db&period;entity&period;Event<br &sol;><br &sol;>class EventRepository&lpar;private val eventDao&colon; EventsDao&rpar; &lbrace;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; get all the events<&sol;span><&sol;strong><br &sol;> fun getAllEvents&lpar;&rpar;&colon; LiveData&lt&semi;List&lt&semi;Event&gt&semi;&gt&semi; &equals; eventDao&period;getAllEvents&lpar;&rpar;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; adds an event to our database&period;<&sol;span><&sol;strong><br &sol;> suspend fun insertEvent&lpar;event&colon; Event&rpar; &lbrace;<br &sol;> eventDao&period;insertEvent&lpar;event&rpar;<br &sol;> &rcub;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; deletes an event from database&period;<&sol;span><&sol;strong><br &sol;> suspend fun deleteEvent&lpar;event&colon; Event&rpar; &lbrace;<br &sol;> eventDao&period;deleteEvent&lpar;event&rpar;<br &sol;> &rcub;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; updates an event from database&period;<&sol;span><&sol;strong><br &sol;> suspend fun updateEvent&lpar;event&colon; Event&rpar; &lbrace;<br &sol;> eventDao&period;updateEvent&lpar;event&rpar;<br &sol;> &rcub;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol;delete an event by id&period;<&sol;span><&sol;strong><br &sol;> suspend fun deleteEventById&lpar;id&colon; Int&rpar; &equals; eventDao&period;deleteEventById&lpar;id&rpar;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; delete all events<&sol;span><&sol;strong><br &sol;> suspend fun clearEvent&lpar;&rpar; &equals; eventDao&period;clearEvent&lpar;&rpar;<br &sol;>&rcub;<&sol;pre> &NewLine;<h4><span style&equals;"color&colon; &num;000080&semi;"><strong>Setup the ViewModel<&sol;strong><&sol;span><&sol;h4> &NewLine;<p>The <strong><span style&equals;"color&colon; &num;008000&semi;">EventViewModel<&sol;span><&sol;strong> class extends the AndroidViewModel&period; <&sol;p> &NewLine;<p>ViewModel is basically used for providing the data to our UI&period; It acts as a communication layer between Repository and the UI&period;<&sol;p> &NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">EventViewModel&period;kt<&sol;span><&sol;strong><&sol;p> &NewLine;<pre>import android&period;app&period;Application<br &sol;>import androidx&period;lifecycle&period;AndroidViewModel<br &sol;>import androidx&period;lifecycle&period;LiveData<br &sol;>import androidx&period;lifecycle&period;viewModelScope<br &sol;>import com&period;c1ctech&period;mvvmwithroomdb&period;data&period;db&period;EventDatabase<br &sol;>import com&period;c1ctech&period;mvvmwithroomdb&period;data&period;db&period;entity&period;Event<br &sol;>import com&period;c1ctech&period;mvvmwithroomdb&period;data&period;repository&period;EventRepository<br &sol;>import kotlinx&period;coroutines&period;Dispatchers<br &sol;>import kotlinx&period;coroutines&period;launch<br &sol;><br &sol;>class EventViewModel&lpar;<br &sol;> application&colon; Application<br &sol;>&rpar; &colon; AndroidViewModel&lpar;application&rpar; &lbrace;<br &sol;><br &sol;> val allEvents&colon; LiveData&lt&semi;List&lt&semi;Event&gt&semi;&gt&semi;<br &sol;> val repository&colon; EventRepository<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; initialize dao&comma; repository and all events<&sol;span><&sol;strong><br &sol;> init &lbrace;<br &sol;> val dao &equals; EventDatabase&period;getDatabase&lpar;application&rpar;&period;getEventsDao&lpar;&rpar;<br &sol;> repository &equals; EventRepository&lpar;dao&rpar;<br &sol;> allEvents &equals; repository&period;getAllEvents&lpar;&rpar;<br &sol;> &rcub;<br &sol;><br &sol;> fun insertEvent&lpar;event&colon; Event&rpar; &equals;<br &sol;> viewModelScope&period;launch&lpar;Dispatchers&period;IO&rpar; &lbrace; repository&period;insertEvent&lpar;event&rpar; &rcub;<br &sol;><br &sol;> fun updateEvent&lpar;event&colon; Event&rpar; &equals;<br &sol;> viewModelScope&period;launch&lpar;Dispatchers&period;IO&rpar; &lbrace; repository&period;updateEvent&lpar;event&rpar; &rcub;<br &sol;><br &sol;> fun deleteEvent&lpar;event&colon; Event&rpar; &equals;<br &sol;> viewModelScope&period;launch&lpar;Dispatchers&period;IO&rpar; &lbrace; repository&period;deleteEvent&lpar;event&rpar; &rcub;<br &sol;><br &sol;> fun deleteEventById&lpar;id&colon; Int&rpar; &equals;<br &sol;> viewModelScope&period;launch&lpar;Dispatchers&period;IO&rpar; &lbrace; repository&period;deleteEventById&lpar;id&rpar; &rcub;<br &sol;><br &sol;> fun clearEvent&lpar;&rpar; &equals;<br &sol;> viewModelScope&period;launch&lpar;Dispatchers&period;IO&rpar; &lbrace; repository&period;clearEvent&lpar;&rpar; &rcub;<br &sol;>&rcub;<&sol;pre> &NewLine;<h4><span style&equals;"color&colon; &num;000080&semi;"><strong>Creating Activity Layout file<&sol;strong><&sol;span><&sol;h4> &NewLine;<p>The below layout file contains a RecyclerView and a FloatingActionButton on click of which we will add an event to the database&period;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>activity&lowbar;main&period;xml<&sol;strong><&sol;span><&sol;p> &NewLine;<pre>&lt&semi;&quest;xml version&equals;"1&period;0" encoding&equals;"utf-8"&quest;&gt&semi;<br &sol;>&lt&semi;RelativeLayout xmlns&colon;android&equals;"http&colon;&sol;&sol;schemas&period;android&period;com&sol;apk&sol;res&sol;android"<br &sol;> xmlns&colon;app&equals;"http&colon;&sol;&sol;schemas&period;android&period;com&sol;apk&sol;res-auto"<br &sol;> xmlns&colon;tools&equals;"http&colon;&sol;&sol;schemas&period;android&period;com&sol;tools"<br &sol;> android&colon;layout&lowbar;width&equals;"match&lowbar;parent"<br &sol;> android&colon;layout&lowbar;height&equals;"match&lowbar;parent"<br &sol;> android&colon;background&equals;"&commat;color&sol;white"<br &sol;> tools&colon;context&equals;"&period;MainActivity"&gt&semi;<br &sol;><br &sol;> &lt&semi;androidx&period;recyclerview&period;widget&period;RecyclerView<br &sol;> android&colon;id&equals;"&commat;&plus;id&sol;eventsRV"<br &sol;> android&colon;layout&lowbar;width&equals;"match&lowbar;parent"<br &sol;> android&colon;layout&lowbar;height&equals;"match&lowbar;parent"<br &sol;> android&colon;layout&lowbar;marginTop&equals;"5dp"<br &sol;> tools&colon;listitem&equals;"&commat;layout&sol;event&lowbar;rv&lowbar;item" &sol;&gt&semi;<br &sol;><br &sol;> &lt&semi;com&period;google&period;android&period;material&period;floatingactionbutton&period;FloatingActionButton<br &sol;> android&colon;id&equals;"&commat;&plus;id&sol;fab&lowbar;add"<br &sol;> android&colon;layout&lowbar;width&equals;"wrap&lowbar;content"<br &sol;> android&colon;layout&lowbar;height&equals;"wrap&lowbar;content"<br &sol;> android&colon;layout&lowbar;alignParentEnd&equals;"true"<br &sol;> android&colon;layout&lowbar;alignParentRight&equals;"true"<br &sol;> android&colon;layout&lowbar;alignParentBottom&equals;"true"<br &sol;> android&colon;layout&lowbar;margin&equals;"20dp"<br &sol;> android&colon;src&equals;"&commat;android&colon;drawable&sol;ic&lowbar;input&lowbar;add"<br &sol;> app&colon;tint&equals;"&commat;color&sol;white" &sol;&gt&semi;<br &sol;><br &sol;>&lt&semi;&sol;RelativeLayout&gt&semi;<&sol;pre> &NewLine;<h4><span style&equals;"color&colon; &num;000080&semi;"><strong>Creating Adapter Layout file<&sol;strong><&sol;span><&sol;h4> &NewLine;<p>The below layout file represents the UI of each item of recyclerView&period;<&sol;p>&NewLine;<&excl;-- WP QUADS Content Ad Plugin v&period; 2&period;0&period;98&period;1 -->&NewLine;<div class&equals;"quads-location quads-ad2" id&equals;"quads-ad2" style&equals;"float&colon;none&semi;margin&colon;0px&semi;">&NewLine;&NewLine;<&sol;div>&NewLine; &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>event&lowbar;rv&lowbar;item&period;xml<&sol;strong><&sol;span><&sol;p> &NewLine;<pre>&lt&semi;&quest;xml version&equals;"1&period;0" encoding&equals;"utf-8"&quest;&gt&semi;<br &sol;>&lt&semi;androidx&period;cardview&period;widget&period;CardView xmlns&colon;android&equals;"http&colon;&sol;&sol;schemas&period;android&period;com&sol;apk&sol;res&sol;android"<br &sol;> xmlns&colon;app&equals;"http&colon;&sol;&sol;schemas&period;android&period;com&sol;apk&sol;res-auto"<br &sol;> xmlns&colon;tools&equals;"http&colon;&sol;&sol;schemas&period;android&period;com&sol;tools"<br &sol;> android&colon;layout&lowbar;width&equals;"match&lowbar;parent"<br &sol;> android&colon;layout&lowbar;height&equals;"wrap&lowbar;content"<br &sol;> android&colon;layout&lowbar;marginStart&equals;"8dp"<br &sol;> android&colon;layout&lowbar;marginTop&equals;"4dp"<br &sol;> android&colon;layout&lowbar;marginEnd&equals;"8dp"<br &sol;> android&colon;layout&lowbar;marginBottom&equals;"4dp"<br &sol;> app&colon;cardBackgroundColor&equals;"&commat;color&sol;teal&lowbar;700"<br &sol;> app&colon;cardCornerRadius&equals;"3dp"<br &sol;> app&colon;cardElevation&equals;"3dp"&gt&semi;<br &sol;><br &sol;> &lt&semi;androidx&period;constraintlayout&period;widget&period;ConstraintLayout<br &sol;> android&colon;layout&lowbar;width&equals;"match&lowbar;parent"<br &sol;> android&colon;layout&lowbar;height&equals;"match&lowbar;parent"&gt&semi;<br &sol;><br &sol;> &lt&semi;TextView<br &sol;> android&colon;id&equals;"&commat;&plus;id&sol;tvTitle"<br &sol;> android&colon;layout&lowbar;width&equals;"0dp"<br &sol;> android&colon;layout&lowbar;height&equals;"wrap&lowbar;content"<br &sol;> android&colon;layout&lowbar;marginStart&equals;"8dp"<br &sol;> android&colon;layout&lowbar;marginLeft&equals;"8dp"<br &sol;> android&colon;layout&lowbar;marginTop&equals;"8dp"<br &sol;> android&colon;layout&lowbar;marginEnd&equals;"8dp"<br &sol;> android&colon;layout&lowbar;marginRight&equals;"8dp"<br &sol;> android&colon;textColor&equals;"&commat;android&colon;color&sol;white"<br &sol;> android&colon;textSize&equals;"24sp"<br &sol;> android&colon;textStyle&equals;"bold"<br &sol;> app&colon;layout&lowbar;constraintStart&lowbar;toStartOf&equals;"parent"<br &sol;> app&colon;layout&lowbar;constraintTop&lowbar;toTopOf&equals;"parent"<br &sol;> tools&colon;text&equals;"Title" &sol;&gt&semi;<br &sol;><br &sol;> &lt&semi;TextView<br &sol;> android&colon;id&equals;"&commat;&plus;id&sol;tvDescription"<br &sol;> android&colon;layout&lowbar;width&equals;"0dp"<br &sol;> android&colon;layout&lowbar;height&equals;"wrap&lowbar;content"<br &sol;> android&colon;layout&lowbar;marginStart&equals;"8dp"<br &sol;> android&colon;layout&lowbar;marginLeft&equals;"8dp"<br &sol;> android&colon;layout&lowbar;marginEnd&equals;"8dp"<br &sol;> android&colon;layout&lowbar;marginRight&equals;"8dp"<br &sol;> android&colon;layout&lowbar;marginBottom&equals;"8dp"<br &sol;> android&colon;textColor&equals;"&commat;color&sol;white"<br &sol;> android&colon;textSize&equals;"16sp"<br &sol;> app&colon;layout&lowbar;constraintBottom&lowbar;toBottomOf&equals;"parent"<br &sol;> app&colon;layout&lowbar;constraintEnd&lowbar;toEndOf&equals;"parent"<br &sol;> app&colon;layout&lowbar;constraintStart&lowbar;toStartOf&equals;"parent"<br &sol;> app&colon;layout&lowbar;constraintTop&lowbar;toBottomOf&equals;"&commat;&plus;id&sol;tvTitle"<br &sol;> app&colon;layout&lowbar;constraintVertical&lowbar;bias&equals;"0&period;0"<br &sol;> tools&colon;text&equals;"Description" &sol;&gt&semi;<br &sol;><br &sol;> &lt&semi;ImageView<br &sol;> android&colon;id&equals;"&commat;&plus;id&sol;imgDelete"<br &sol;> android&colon;layout&lowbar;width&equals;"wrap&lowbar;content"<br &sol;> android&colon;layout&lowbar;height&equals;"wrap&lowbar;content"<br &sol;> android&colon;layout&lowbar;marginTop&equals;"8dp"<br &sol;> android&colon;layout&lowbar;marginEnd&equals;"8dp"<br &sol;> android&colon;layout&lowbar;marginRight&equals;"8dp"<br &sol;> android&colon;src&equals;"&commat;drawable&sol;ic&lowbar;delete"<br &sol;> android&colon;textSize&equals;"24sp"<br &sol;> android&colon;textStyle&equals;"bold"<br &sol;> app&colon;layout&lowbar;constraintEnd&lowbar;toEndOf&equals;"parent"<br &sol;> app&colon;layout&lowbar;constraintTop&lowbar;toTopOf&equals;"parent" &sol;&gt&semi;<br &sol;><br &sol;> &lt&semi;&sol;androidx&period;constraintlayout&period;widget&period;ConstraintLayout&gt&semi;<br &sol;><br &sol;>&lt&semi;&sol;androidx&period;cardview&period;widget&period;CardView&gt&semi;<&sol;pre> &NewLine;<h4><span style&equals;"color&colon; &num;000080&semi;"><strong>Creating Adapter class<&sol;strong><&sol;span><&sol;h4> &NewLine;<p>The EventAdapter is an adapter class for the recycler view to set all the items into recycler view&period;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>EventAdapter&period;kt<&sol;strong><&sol;span><&sol;p> &NewLine;<pre>import android&period;view&period;LayoutInflater<br &sol;>import android&period;view&period;ViewGroup<br &sol;>import androidx&period;recyclerview&period;widget&period;RecyclerView<br &sol;>import com&period;c1ctech&period;mvvmwithroomdb&period;data&period;db&period;entity&period;Event<br &sol;>import com&period;c1ctech&period;mvvmwithroomdb&period;databinding&period;EventRvItemBinding<br &sol;><br &sol;>class EventAdapter&lpar;<br &sol;> val eventDeleteIconClickInterface&colon; EventDeleteIconClickInterface&comma;<br &sol;> val eventClickInterface&colon; EventClickInterface<br &sol;>&rpar; &colon; RecyclerView&period;Adapter&lt&semi;EventViewHolder&gt&semi;&lpar;&rpar; &lbrace;<br &sol;><br &sol;> private val allEvents &equals; ArrayList&lt&semi;Event&gt&semi;&lpar;&rpar;<br &sol;><br &sol;> override fun onCreateViewHolder&lpar;parent&colon; ViewGroup&comma; viewType&colon; Int&rpar;&colon; EventViewHolder &lbrace;<br &sol;><br &sol;> val inflater &equals; LayoutInflater&period;from&lpar;parent&period;context&rpar;<br &sol;><br &sol;> val binding &equals; EventRvItemBinding&period;inflate&lpar;inflater&comma; parent&comma; false&rpar;<br &sol;> return EventViewHolder&lpar;binding&rpar;<br &sol;> &rcub;<br &sol;><br &sol;> override fun onBindViewHolder&lpar;holder&colon; EventViewHolder&comma; position&colon; Int&rpar; &lbrace;<br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; sets data to item of recycler view&period;<&sol;span><&sol;strong><br &sol;> holder&period;binding&period;tvTitle&period;text &equals; allEvents&period;get&lpar;position&rpar;&period;title<br &sol;> holder&period;binding&period;tvDescription&period;text &equals; allEvents&period;get&lpar;position&rpar;&period;description<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; adding click listener to our delete image view icon&period;<&sol;span><&sol;strong><br &sol;> holder&period;binding&period;imgDelete&period;setOnClickListener &lbrace;<br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; call eventDeleteIconClickInterface&period;onEventDeleteIconClick&lpar;&rpar; and pass position to it&period;<&sol;span><&sol;strong><br &sol;> eventDeleteIconClickInterface&period;onEventDeleteIconClick&lpar;allEvents&period;get&lpar;position&rpar;&rpar;<br &sol;> &rcub;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; adding click listener to our recycler view item&period;<&sol;span><&sol;strong><br &sol;> holder&period;itemView&period;setOnClickListener &lbrace;<br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; call eventClickInterface&period;onEventClick&lpar;&rpar; and pass position to it&period;<&sol;span><&sol;strong><br &sol;> eventClickInterface&period;onEventClick&lpar;allEvents&period;get&lpar;position&rpar;&rpar;<br &sol;> &rcub;<br &sol;> &rcub;<br &sol;><br &sol;> override fun getItemCount&lpar;&rpar;&colon; Int &lbrace;<br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; return list size&period;<&sol;span><&sol;strong><br &sol;> return allEvents&period;size<br &sol;> &rcub;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; update the list of events&period;<&sol;span><&sol;strong><br &sol;> fun updateList&lpar;newList&colon; List&lt&semi;Event&gt&semi;&rpar; &lbrace;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; clear the allEvents array list<&sol;span><&sol;strong><br &sol;> allEvents&period;clear&lpar;&rpar;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; adds a new list to our allEvents list&period;<&sol;span><&sol;strong><br &sol;> allEvents&period;addAll&lpar;newList&rpar;<br &sol;><br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; call notifyDataSetChanged&lpar;&rpar; to notify our adapter&period;<&sol;span><&sol;strong><br &sol;> notifyDataSetChanged&lpar;&rpar;<br &sol;> &rcub;<br &sol;>&rcub;<br &sol;><br &sol;>interface EventDeleteIconClickInterface &lbrace;<br &sol;> <strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; creating a method for click<&sol;span><&sol;strong><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; action on delete image view&period;<&sol;span><&sol;strong><br &sol;> fun onEventDeleteIconClick&lpar;event&colon; Event&rpar;<br &sol;>&rcub;<br &sol;><br &sol;>interface EventClickInterface &lbrace;<br &sol;> <strong><span style&equals;"color&colon; &num;008000&semi;">&sol;&sol; creating a method for click action<&sol;span><&sol;strong><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; on recycler view item for updating it&period;<&sol;span><&sol;strong><br &sol;> fun onEventClick&lpar;event&colon; Event&rpar;<br &sol;>&rcub;<br &sol;><br &sol;>class EventViewHolder&lpar;val binding&colon; EventRvItemBinding&rpar; &colon; RecyclerView&period;ViewHolder&lpar;binding&period;root&rpar; &lbrace;&rcub;<&sol;pre> &NewLine;<h4><span style&equals;"color&colon; &num;000080&semi;"><strong>Creating AddEventActivity File<&sol;strong><&sol;span><&sol;h4> &NewLine;<p>Inside AddEventActivity&comma; we will add and edit an event&period;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>AddEventActivity<&sol;strong><strong>&period;kt<&sol;strong><&sol;span><&sol;p> &NewLine;<pre>import android&period;content&period;Intent<br &sol;>import android&period;os&period;Bundle<br &sol;>import android&period;widget&period;Toast<br &sol;>import androidx&period;appcompat&period;app&period;AppCompatActivity<br &sol;>import androidx&period;lifecycle&period;ViewModelProvider<br &sol;>import com&period;c1ctech&period;mvvmwithroomdb&period;data&period;db&period;entity&period;Event<br &sol;>import com&period;c1ctech&period;mvvmwithroomdb&period;databinding&period;ActivityAddEventBinding<br &sol;><br &sol;>class AddEventActivity &colon; AppCompatActivity&lpar;&rpar; &lbrace;<br &sol;> private lateinit var binding&colon; ActivityAddEventBinding<br &sol;> lateinit var viewModal&colon; EventViewModel<br &sol;> var eventID &equals; -1&semi;<br &sol;><br &sol;> override fun onCreate&lpar;savedInstanceState&colon; Bundle&quest;&rpar; &lbrace;<br &sol;> super&period;onCreate&lpar;savedInstanceState&rpar;<br &sol;> binding &equals; ActivityAddEventBinding&period;inflate&lpar;layoutInflater&rpar;<br &sol;> setContentView&lpar;binding&period;root&rpar;<br &sol;><br &sol;><span style&equals;"color&colon; &num;008000&semi;"><strong> &sol;&sol; initializes the viewmodel&period;<&sol;strong><&sol;span><br &sol;> viewModal &equals; ViewModelProvider&lpar;<br &sol;> this&comma;<br &sol;> ViewModelProvider&period;AndroidViewModelFactory&period;getInstance&lpar;application&rpar;<br &sol;> &rpar;&period;get&lpar;EventViewModel&colon;&colon;class&period;java&rpar;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; getting data passed via an intent&period;<&sol;span><&sol;strong><br &sol;> val eventType &equals; intent&period;getStringExtra&lpar;"eventType"&rpar;<br &sol;> if &lpar;eventType&period;equals&lpar;"Edit"&rpar;&rpar; &lbrace;<br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; setting data to edit text&period;<&sol;span><&sol;strong><br &sol;> val eventTitle &equals; intent&period;getStringExtra&lpar;"eventTitle"&rpar;<br &sol;> val eventDescription &equals; intent&period;getStringExtra&lpar;"eventDescription"&rpar;<br &sol;> eventID &equals; intent&period;getIntExtra&lpar;"eventId"&comma; -1&rpar;<br &sol;> binding&period;btnSave&period;setText&lpar;"Update Event"&rpar;<br &sol;> binding&period;titleET&period;setText&lpar;eventTitle&rpar;<br &sol;> binding&period;descriptionET&period;setText&lpar;eventDescription&rpar;<br &sol;> &rcub; else &lbrace;<br &sol;> binding&period;btnSave&period;setText&lpar;"Save Event"&rpar;<br &sol;> &rcub;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; adding click listener to our save button&period;<&sol;span><&sol;strong><br &sol;> binding&period;btnSave&period;setOnClickListener &lbrace;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; getting title and desc from edit text&period;<&sol;span><&sol;strong><br &sol;> val eventTitle &equals; binding&period;titleET&period;text&period;toString&lpar;&rpar;<br &sol;> val eventDescription &equals; binding&period;descriptionET&period;text&period;toString&lpar;&rpar;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; checking the type and then saving or updating the data&period;<&sol;span><&sol;strong><br &sol;> if &lpar;eventType&period;equals&lpar;"Edit"&rpar;&rpar; &lbrace;<br &sol;><br &sol;> if &lpar;eventTitle&period;isNotEmpty&lpar;&rpar; &amp&semi;&amp&semi; eventDescription&period;isNotEmpty&lpar;&rpar;&rpar; &lbrace;<br &sol;><br &sol;> val updatedEvent &equals; Event&lpar;eventID&comma; eventTitle&comma; eventDescription&rpar;<br &sol;> viewModal&period;updateEvent&lpar;updatedEvent&rpar;<br &sol;> Toast&period;makeText&lpar;this&comma; "Event Updated"&comma; Toast&period;LENGTH&lowbar;LONG&rpar;&period;show&lpar;&rpar;<br &sol;> &rcub;<br &sol;> &rcub; else &lbrace;<br &sol;> if &lpar;eventTitle&period;isNotEmpty&lpar;&rpar; &amp&semi;&amp&semi; eventDescription&period;isNotEmpty&lpar;&rpar;&rpar; &lbrace;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; if the string is not empty we are calling<&sol;span><&sol;strong><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; add event method to add data to our room database&period;<&sol;span><&sol;strong><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol;why id null&quest; because id is auto generate<&sol;span><&sol;strong><br &sol;> viewModal&period;insertEvent&lpar;Event&lpar;null&comma; eventTitle&comma; eventDescription&rpar;&rpar;<br &sol;> Toast&period;makeText&lpar;this&comma; "Event Added"&comma; Toast&period;LENGTH&lowbar;LONG&rpar;&period;show&lpar;&rpar;<br &sol;> &rcub;<br &sol;> &rcub;<br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; opening the new activity<&sol;span><&sol;strong><br &sol;> startActivity&lpar;Intent&lpar;applicationContext&comma; MainActivity&colon;&colon;class&period;java&rpar;&rpar;<br &sol;> this&period;finish&lpar;&rpar;<br &sol;> &rcub;<br &sol;> &rcub;<br &sol;>&rcub;<&sol;pre> &NewLine;<h4><span style&equals;"color&colon; &num;000080&semi;"><strong>Creating MainActivity File<&sol;strong><&sol;span><&sol;h4> &NewLine;<p>Inside MainActivity&comma; we will get an instance of ViewModel and use ViewModel properties which will execute the SQL queries and update the UI accordingly&period;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>MainActivity&period;kt<&sol;strong><&sol;span><&sol;p> &NewLine;<pre>import android&period;content&period;Intent<br &sol;>import android&period;os&period;Bundle<br &sol;>import android&period;view&period;Menu<br &sol;>import android&period;view&period;MenuItem<br &sol;>import android&period;widget&period;Toast<br &sol;>import androidx&period;appcompat&period;app&period;AlertDialog<br &sol;>import androidx&period;appcompat&period;app&period;AppCompatActivity<br &sol;>import androidx&period;lifecycle&period;Observer<br &sol;>import androidx&period;lifecycle&period;ViewModelProvider<br &sol;>import androidx&period;recyclerview&period;widget&period;LinearLayoutManager<br &sol;>import com&period;c1ctech&period;mvvmwithroomdb&period;data&period;db&period;entity&period;Event<br &sol;>import com&period;c1ctech&period;mvvmwithroomdb&period;databinding&period;ActivityMainBinding<br &sol;><br &sol;>class MainActivity &colon; AppCompatActivity&lpar;&rpar;&comma; EventClickInterface&comma; EventDeleteIconClickInterface &lbrace;<br &sol;><br &sol;> private lateinit var binding&colon; ActivityMainBinding<br &sol;> private lateinit var viewModel&colon; EventViewModel<br &sol;> private lateinit var eventAdapter&colon; EventAdapter<br &sol;><br &sol;> override fun onCreate&lpar;savedInstanceState&colon; Bundle&quest;&rpar; &lbrace;<br &sol;> super&period;onCreate&lpar;savedInstanceState&rpar;<br &sol;> binding &equals; ActivityMainBinding&period;inflate&lpar;layoutInflater&rpar;<br &sol;> setContentView&lpar;binding&period;root&rpar;<br &sol;><br &sol;> viewModel &equals; ViewModelProvider&lpar;<br &sol;> this&comma;<br &sol;> ViewModelProvider&period;AndroidViewModelFactory&period;getInstance&lpar;application&rpar;<br &sol;> &rpar;&period;get&lpar;EventViewModel&colon;&colon;class&period;java&rpar;<br &sol;><br &sol;> eventAdapter &equals; EventAdapter&lpar;this&comma; this&rpar;<br &sol;><br &sol;> initView&lpar;&rpar;<br &sol;> observeEvents&lpar;&rpar;<br &sol;> &rcub;<br &sol;><br &sol;> private fun initView&lpar;&rpar; &lbrace;<br &sol;> binding&period;fabAdd&period;setOnClickListener &lbrace;<br &sol;> val intent &equals; Intent&lpar;this&comma; AddEventActivity&colon;&colon;class&period;java&rpar;<br &sol;> startActivity&lpar;intent&rpar;<br &sol;> &rcub;<br &sol;><br &sol;> binding&period;eventsRV&period;apply &lbrace;<br &sol;> setHasFixedSize&lpar;true&rpar;<br &sol;> layoutManager &equals; LinearLayoutManager&lpar;this&commat;MainActivity&rpar;<br &sol;> adapter &equals; eventAdapter<br &sol;> &rcub;<br &sol;> &rcub;<br &sol;><br &sol;> private fun observeEvents&lpar;&rpar; &lbrace;<br &sol;> viewModel&period;allEvents&period;observe&lpar;this&comma; Observer &lbrace; list -&gt&semi;<br &sol;> list&quest;&period;let &lbrace;<br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; updates the list&period;<&sol;span><&sol;strong><br &sol;> eventAdapter&period;updateList&lpar;it&rpar;<br &sol;> &rcub;<br &sol;> &rcub;&rpar;<br &sol;> &rcub;<br &sol;><br &sol;> private fun clearEvent&lpar;&rpar; &lbrace;<br &sol;> val dialog &equals; AlertDialog&period;Builder&lpar;this&comma; R&period;style&period;ThemeOverlay&lowbar;AppCompat&lowbar;Dialog&rpar;<br &sol;> dialog&period;setTitle&lpar;"Clear Event"&rpar;<br &sol;> &period;setMessage&lpar;"Are you sure&comma; you want to delete all event&quest;"&rpar;<br &sol;> &period;setPositiveButton&lpar;android&period;R&period;string&period;ok&rpar; &lbrace; &lowbar;&comma; &lowbar; -&gt&semi;<br &sol;> viewModel&period;clearEvent&lpar;&rpar;&period;also &lbrace;<br &sol;> Toast&period;makeText&lpar;this&comma; "Event Deleted"&comma; Toast&period;LENGTH&lowbar;LONG&rpar;&period;show&lpar;&rpar;<br &sol;> &rcub;<br &sol;> &rcub;&period;setNegativeButton&lpar;android&period;R&period;string&period;cancel&comma; null&rpar;&period;create&lpar;&rpar;&period;show&lpar;&rpar;<br &sol;> &rcub;<br &sol;><br &sol;> override fun onCreateOptionsMenu&lpar;menu&colon; Menu&quest;&rpar;&colon; Boolean &lbrace;<br &sol;> menuInflater&period;inflate&lpar;R&period;menu&period;main&lowbar;menu&comma; menu&rpar;<br &sol;> return true<br &sol;> &rcub;<br &sol;><br &sol;> override fun onOptionsItemSelected&lpar;item&colon; MenuItem&rpar;&colon; Boolean &lbrace;<br &sol;> when &lpar;item&period;itemId&rpar; &lbrace;<br &sol;> R&period;id&period;clearEventItem -&gt&semi; clearEvent&lpar;&rpar;<br &sol;> &rcub;<br &sol;> return super&period;onOptionsItemSelected&lpar;item&rpar;<br &sol;> &rcub;<br &sol;><br &sol;> override fun onEventDeleteIconClick&lpar;event&colon; Event&rpar; &lbrace;<br &sol;> viewModel&period;deleteEvent&lpar;event&rpar;<br &sol;> Toast&period;makeText&lpar;this&comma; "Event Deleted"&comma; Toast&period;LENGTH&lowbar;LONG&rpar;&period;show&lpar;&rpar;<br &sol;> &rcub;<br &sol;><br &sol;> override fun onEventClick&lpar;event&colon; Event&rpar; &lbrace;<br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; opening a new intent and passing a data to it&period;<&sol;span><&sol;strong><br &sol;> val intent &equals; Intent&lpar;this&commat;MainActivity&comma; AddEventActivity&colon;&colon;class&period;java&rpar;<br &sol;> intent&period;putExtra&lpar;"eventType"&comma; "Edit"&rpar;<br &sol;> intent&period;putExtra&lpar;"eventTitle"&comma; event&period;title&rpar;<br &sol;> intent&period;putExtra&lpar;"eventDescription"&comma; event&period;description&rpar;<br &sol;> intent&period;putExtra&lpar;"eventId"&comma; event&period;id&rpar;<br &sol;> startActivity&lpar;intent&rpar;<br &sol;> this&period;finish&lpar;&rpar;<br &sol;> &rcub;<br &sol;>&rcub;<&sol;pre> &NewLine;<p>When you run the app it will look like this&colon;<&sol;p> &NewLine;<p><img class&equals;"alignnone wp-image-3130" src&equals;"https&colon;&sol;&sol;c1ctech&period;com&sol;wp-content&sol;uploads&sol;2022&sol;02&sol;Screenshot&lowbar;20220225-160056&lowbar;MVVMWithRoomDB-498x1024&period;jpg" alt&equals;"" width&equals;"385" height&equals;"792" &sol;>&NewLine;

Exit mobile version