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

Postingan populer dari blog ini

Protect API KEY in Android Development