In this Android example tutorial we will work with Room database with update the Live data using ViewModel. In this ViewModel example we are creating the ViewModel object by passing arguments.
To pass arguments to ViewModel constructor we will use ViewModelFactory pattern. Handle the Live data update using LiveData Jetpack component.
In this example we will store Employee data in the Room Database and fetch all employees data from database and display them on the RecyclerView using viewmodel. To update the live data we use LiveData component.
So let's implement Room database with ViewModel Live Data
Step 1: Create Android application in Android studio
Step 2: Add required dependencies in build.gradle file
def lifecycle_version = "2.3.1" //implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" // ViewModel implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" // ViewModel utilities for Compose // LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version" // Room support def room_version = "2.3.0" implementation "androidx.room:room-runtime:$room_version" kapt "androidx.room:room-compiler:$room_version" // Anko Commons implementation "org.jetbrains.anko:anko-commons:0.10.5" // RecyclerView implementation 'androidx.recyclerview:recyclerview:1.2.1' |
We added dependencies for Room Database, LiveData, ViewModel and RecyclerView
Step 3: Room Database Integration
To work with Room Database we need to create Room Database instance and Dao classes and Entities. Read more about Room Database in Android.
Create Room Database instance
Here we are creating the singleton instance for Room Database using kotlin companion object.
companion object{ private var INSTANCE: RoomSingleton? = null fun getInstance(context:Context): RoomSingleton{ if (INSTANCE == null){ INSTANCE = Room.databaseBuilder( context, RoomSingleton::class.java, "roomdb") .build() } return INSTANCE as RoomSingleton } } |
Create Employee Entity
Create our employee entity with two fields, id auto increment and name
package com.rrtutors import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey @Entity(tableName = "employeeTbl") data class Emplyee( @PrimaryKey var id:Long?, @ColumnInfo(name = "uuid") var name: String ) |
Here we are creating the Employee name dynamically unique id generation by android UUID.
Create DAO classes
To communicate Entity and Database we will use DAO classes. Let's create EmployeeDao interface.
package com.rrtutors import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query @Dao interface EmployeeDao{ @Query("SELECT * FROM employeeTbl ORDER BY id DESC") fun allEmplyees(): LiveData<List<Emplyee>> @Insert(onConflict = OnConflictStrategy.REPLACE) fun insert(student: Emplyee) } |
Update DAO and Entity classes inside Database class, finaly our singleton Database classes will be like below
package com.rrtutors import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase import android.content.Context @Database(entities = arrayOf(Emplyee::class), version = 1, exportSchema = false) abstract class RoomSingleton : RoomDatabase(){ abstract fun employeeDao():EmployeeDao companion object{ private var INSTANCE: RoomSingleton? = null fun getInstance(context:Context): RoomSingleton{ if (INSTANCE == null){ INSTANCE = Room.databaseBuilder( context, RoomSingleton::class.java, "roomdb") .build() } return INSTANCE as RoomSingleton } } } |
Step 4: Create ViewModel and Live Data
In this example we are creating the Employee ViewModel with parameterize constructor. To pass arguments to ViewModel we will use ViewModelFactory pattern.
So create two classes EmployeeViewModel and EmployeeViewModelFactory
EmployeeViewModel:
By extend the ViewModel we will create EmployeeViewModel class
class EmployeeViewModel(var application:Application):ViewModel()
{
}
|
EmployeeViewModelFactory
package com.rrtutors import android.app.Application import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider class EmployeeViewModelFactory(var application: Application): ViewModelProvider.Factory { override fun <T : ViewModel?> create(modelClass: Class<T>): T { if (modelClass.isAssignableFrom(EmployeeViewModel::class.java)) { return EmployeeViewModel(application) as T } throw IllegalArgumentException("Unknown ViewModel class") } } |
Now Let's Add our Database within the ViewModel and add LiveData by fetch the data from database
Finally our EmployeeViewModel class will be like below
package com.rrtutors import androidx.lifecycle.LiveData import android.app.Application import androidx.lifecycle.ViewModel class EmployeeViewModel(var application:Application):ViewModel() { private val db:RoomSingleton = RoomSingleton.getInstance(application) internal val allEmplyees : LiveData<List<Emplyee>> = db.employeeDao().allEmplyees() fun insert(student:Emplyee){ db.employeeDao().insert(student) } } |
Step 5: Add ViewModel to Activity
Now we need to create ViewModel instance inside Activity and insert employee data to database and fetch data from Database using LiveData reflection
In ViewModel we required context, so we will pass this context inside constructor. To create instance of ViewModel with arguments we will use Factory patterns.
So first create instance for EmployeeViewModelFactory, then we will create ViewModel instance
val modelfactory=EmployeeViewModelFactory(application); model = ViewModelProvider(this,modelfactory).get(EmployeeViewModel::class.java) |
To observe the live data changes we will call observe on livedata object
// Observe the model model.allEmplyees.observe(this, Observer{ students-> // Data bind the recycler view recyclerView.adapter = RecyclerViewAdapter(students) }) |
on tap on button we will insert Employee data into Room database by
btn.setOnClickListener { doAsync { model.insert(Emplyee(null, UUID.randomUUID().toString())) } } |
We know that Room database operations can't run on main thread so we run these operations inside asynchronously. TO do this we used Anko async library.
Finally our Activity could be like this
package com.rrtutors import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Button import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import org.jetbrains.anko.doAsync import java.util.* class MainActivity : AppCompatActivity() { lateinit var recyclerView:RecyclerView; lateinit var btn:Button; private lateinit var model: EmployeeViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) recyclerView=findViewById<RecyclerView>(R.id.recyclerView) btn=findViewById<Button>(R.id.btn) // Get the view model val modelfactory=EmployeeViewModelFactory(application); model = ViewModelProvider(this,modelfactory).get(EmployeeViewModel::class.java) // Specify layout for recycler view val linearLayoutManager = LinearLayoutManager( this, RecyclerView.VERTICAL,false) recyclerView.layoutManager = linearLayoutManager // Observe the model model.allEmplyees.observe(this, Observer{ students-> // Data bind the recycler view recyclerView.adapter = RecyclerViewAdapter(students) }) // Insert data into table btn.setOnClickListener { doAsync { model.insert(Emplyee(null, UUID.randomUUID().toString())) } } } } |
Conclusion: In this Android Room database tutorial we covered how to work with ViewModel with LiveData and Create ViewModel instance by ViewModelFactory pattern.
Article Contributed By :
|
|
|
|
859 Views |