Learn CRUD with Room Android Kotlin
- setup build.gradle
plugins {
id 'kotlin-kapt'
id 'kotlin-parcelize'
}
buildFeatures {
viewBinding true
}
dependencies {
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.0'
implementation 'androidx.room:room-runtime:2.3.0'
kapt 'androidx.room:room-compiler:2.3.0'
}
- create entity
@Entity
@Parcelize
data class Note(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
var id: Int = 0,
@ColumnInfo(name = "title")
var title: String? = null,
@ColumnInfo(name = "description")
var description: String? = null,
@ColumnInfo(name = "date")
var date: String? = null
) : Parcelable
- create dao
@Dao
interface NoteDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(note: Note)
@Update
fun update(note: Note)
@Delete
fun delete(note: Note)
@Query("SELECT * from note ORDER BY id ASC")
fun getAllNotes(): LiveData<List<Note>>
}
- crate database
@Database(entities = [Note::class], version = 1)
abstract class NoteRoomDatabase : RoomDatabase() {
abstract fun noteDao(): NoteDao
companion object {
@Volatile
private var INSTANCE: NoteRoomDatabase? = null
@JvmStatic
fun getDatabase(context: Context): NoteRoomDatabase {
if (INSTANCE == null) {
synchronized(NoteRoomDatabase::class.java) {
INSTANCE = Room.databaseBuilder(context.applicationContext,
NoteRoomDatabase::class.java, "note_database")
.build()
}
}
return INSTANCE as NoteRoomDatabase
}
}
}
- create repository
class NoteRepository(application: Application) {
private val mNotesDao: NoteDao
private val executorService: ExecutorService = Executors.newSingleThreadExecutor()
init {
val db = NoteRoomDatabase.getDatabase(application)
mNotesDao = db.noteDao()
}
fun getAllNotes(): LiveData<List<Note>> = mNotesDao.getAllNotes()
fun insert(note: Note) {
executorService.execute { mNotesDao.insert(note) }
}
fun delete(note: Note) {
executorService.execute { mNotesDao.delete(note) }
}
fun update(note: Note) {
executorService.execute { mNotesDao.update(note) }
}
}
- create view model
class NoteAddUpdateViewModel(application: Application) : ViewModel() {
private val mNoteRepository: NoteRepository = NoteRepository(application)
fun insert(note: Note) {
mNoteRepository.insert(note)
}
fun update(note: Note) {
mNoteRepository.update(note)
}
fun delete(note: Note) {
mNoteRepository.delete(note)
}
}
class MainViewModel(application: Application) : ViewModel() {
private val mNoteRepository: NoteRepository = NoteRepository(application)
fun getAllNotes(): LiveData<List<Note>> = mNoteRepository.getAllNotes()
}
- create view model factory (adding context when called viewmodel in activity)
class ViewModelFactory private constructor(private val mApplication: Application) : ViewModelProvider.NewInstanceFactory() {
companion object {
@Volatile
private var INSTANCE: ViewModelFactory? = null
@JvmStatic
fun getInstance(application: Application): ViewModelFactory {
if (INSTANCE == null) {
synchronized(ViewModelFactory::class.java) {
INSTANCE = ViewModelFactory(application)
}
}
return INSTANCE as ViewModelFactory
}
}
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
return MainViewModel(mApplication) as T
} else if (modelClass.isAssignableFrom(NoteAddUpdateViewModel::class.java)) {
return NoteAddUpdateViewModel(mApplication) as T
}
throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
}
}
- create helper, notediffcallback(checking changes in list note)
class NoteDiffCallback(private val mOldNoteList: List<Note>, private val mNewNoteList: List<Note>) : DiffUtil.Callback() {
override fun getOldListSize(): Int {
return mOldNoteList.size
}
override fun getNewListSize(): Int {
return mNewNoteList.size
}
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return mOldNoteList[oldItemPosition].id == mNewNoteList[newItemPosition].id
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldEmployee = mOldNoteList[oldItemPosition]
val newEmployee = mNewNoteList[newItemPosition]
return oldEmployee.title == newEmployee.title && oldEmployee.description == newEmployee.description
}
}
- inside adapter
fun setListNotes(listNotes: List<Note>) {
val diffCallback = NoteDiffCallback(this.listNotes, listNotes)
val diffResult = DiffUtil.calculateDiff(diffCallback)
this.listNotes.clear()
this.listNotes.addAll(listNotes)
diffResult.dispatchUpdatesTo(this)
}
Komentar
Posting Komentar