diff --git a/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/db/NoteDatabase.kt b/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/db/NoteDatabase.kt index 1c213b2..ce99bfb 100644 --- a/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/db/NoteDatabase.kt +++ b/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/db/NoteDatabase.kt @@ -12,7 +12,7 @@ import com.example.epicdatabaseexample.db.note.NoteDao import com.example.epicdatabaseexample.db.note.NoteEntity @Database( - version = 2, + version = 3, exportSchema = false, entities = [ NoteEntity::class, @@ -39,16 +39,27 @@ abstract class NoteDatabase : RoomDatabase() { private fun migrationList() = arrayOf( object : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("CREATE TABLE $PERSON_TABLE (" + - "${PersonEntity.COLUMN_NAME} TEXT NOT NULL," + - "PRIMARY KEY(${PersonEntity.COLUMN_NAME})" + - ")") - database.execSQL("ALTER TABLE $NOTE_TABLE " + - "ADD COLUMN ${NoteEntity.COLUMN_PERSON_NAME} TEXT NOT NULL " + - "DEFAULT ('${PersonEntity.DEFAULT_PERSON_NAME}')") + database.execSQL( + "CREATE TABLE $PERSON_TABLE (" + + "${PersonEntity.COLUMN_NAME} TEXT NOT NULL," + + "PRIMARY KEY(${PersonEntity.COLUMN_NAME})" + + ")" + ) + database.execSQL( + "ALTER TABLE $NOTE_TABLE " + + "ADD COLUMN ${NoteEntity.COLUMN_PERSON_NAME} TEXT NOT NULL " + + "DEFAULT ('${PersonEntity.DEFAULT_PERSON_NAME}')" + ) } }, - // TODO Добавить миграцию. + object : Migration(2, 3) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL( + "ALTER TABLE $NOTE_TABLE " + + "ADD COLUMN ${NoteEntity.COLUMN_IS_COMPLETED} INTEGER NOT NULL DEFAULT 0" + ) + } + } ) private fun createDatabaseInstance(application: Application): NoteDatabase { diff --git a/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/db/note/NoteDao.kt b/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/db/note/NoteDao.kt index 8645616..3166d04 100644 --- a/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/db/note/NoteDao.kt +++ b/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/db/note/NoteDao.kt @@ -26,8 +26,9 @@ abstract class NoteDao { @Query("DELETE FROM note_table") abstract fun deleteAllNote(): Completable - // TODO Добавить метод для обновления одного элемента. - // Что можно указать в качестве возвращаемого типа? - // Напомню, что выше есть метод observeNoteList, который будет вызываться при любом - // изменении списка в Базе Данных. + @Update + abstract fun updateNote(note: NoteEntity): Completable + + @Query("UPDATE note_table SET is_completed = :isCompleted where id = :noteId") + abstract fun setCompleted(noteId: Int, isCompleted: Boolean): Completable } \ No newline at end of file diff --git a/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/db/note/NoteEntity.kt b/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/db/note/NoteEntity.kt index b42b9b3..7ba0dca 100644 --- a/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/db/note/NoteEntity.kt +++ b/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/db/note/NoteEntity.kt @@ -22,10 +22,8 @@ data class NoteEntity( @ColumnInfo(name = COLUMN_PERSON_NAME) var personName: String = PersonEntity.DEFAULT_PERSON_NAME, - // TODO Нужно добавить нове поле isCompleted типа Boolean. - // В SQLite не поддерживается Boolean, но в Room его можно использовать. - // Поэтому поле делаем именно Boolean, а при добавлении миграции - нужно будет погуглить, - // как обойти это ограничение. + @ColumnInfo(name = COLUMN_IS_COMPLETED) + var isCompleted: Boolean = false ) { companion object { @@ -33,5 +31,6 @@ data class NoteEntity( const val COLUMN_TITLE = "title" const val COLUMN_DESCRIPTION = "descriptions" const val COLUMN_PERSON_NAME = "person_name" + const val COLUMN_IS_COMPLETED = "is_completed" } } \ No newline at end of file diff --git a/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/ui/note_list/NoteDiffUtilCallback.kt b/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/ui/note_list/NoteDiffUtilCallback.kt index 7c8c9af..097d385 100644 --- a/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/ui/note_list/NoteDiffUtilCallback.kt +++ b/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/ui/note_list/NoteDiffUtilCallback.kt @@ -10,6 +10,17 @@ class NoteDiffUtilCallback : DiffUtil.ItemCallback() { } override fun areContentsTheSame(oldItem: NoteEntity, newItem: NoteEntity): Boolean { - return false + return oldItem == newItem } + + override fun getChangePayload(oldItem: NoteEntity, newItem: NoteEntity): Any? { + val isCompletedChanged = oldItem.isCompleted != newItem.isCompleted + return if (isCompletedChanged) + NotePayload(isCompletedChanged) + else null + } + + data class NotePayload( + val isCompleteChanged: Boolean + ) } \ No newline at end of file diff --git a/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/ui/note_list/NoteListAdapter.kt b/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/ui/note_list/NoteListAdapter.kt index 192174f..7170dab 100644 --- a/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/ui/note_list/NoteListAdapter.kt +++ b/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/ui/note_list/NoteListAdapter.kt @@ -20,15 +20,38 @@ class NoteListAdapter( onNoteClick.invoke(note.id) } holder.personName.text = note.personName - // TODO Раскомментировать, после добавления нового поля в NoteEntity. -// holder.isCompleted.setOnClickListener { -// onIsCompletedClick.invoke(note.copy( -// isCompleted = !note.isCompleted -// )) -// } -// val isCompletedChanged = note.isCompleted != holder.isCompleted.isChecked -// if (isCompletedChanged) { -// holder.isCompleted.isChecked = note.isCompleted -// } + holder.isCompleted.setOnClickListener { + onIsCompletedClick.invoke( + note.copy( + isCompleted = !note.isCompleted + ) + ) + } + val isCompletedChanged = note.isCompleted != holder.isCompleted.isChecked + if (isCompletedChanged) { + holder.isCompleted.isChecked = note.isCompleted + } + } + + override fun onBindViewHolder( + holder: NoteViewHolder, + position: Int, + payloads: MutableList + ) { + if (payloads.isEmpty()) { + super.onBindViewHolder(holder, position, payloads) + return + } + val note = getItem(position) + holder.isCompleted.setOnClickListener { + onIsCompletedClick.invoke( + note.copy( + isCompleted = !note.isCompleted + ) + ) + } + val notePayload = payloads.first() as NoteDiffUtilCallback.NotePayload + if (notePayload.isCompleteChanged) + holder.isCompleted.isChecked = note.isCompleted } } \ No newline at end of file diff --git a/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/ui/note_list/NoteListViewModel.kt b/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/ui/note_list/NoteListViewModel.kt index 3344f2c..8594eec 100644 --- a/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/ui/note_list/NoteListViewModel.kt +++ b/EpicDatabseExample/app/src/main/java/com/example/epicdatabaseexample/ui/note_list/NoteListViewModel.kt @@ -35,9 +35,11 @@ class NoteListViewModel constructor( .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe { noteList -> - state.postValue(NoteListViewState( - noteList = noteList - )) + state.postValue( + NoteListViewState( + noteList = noteList + ) + ) } ) } @@ -48,9 +50,11 @@ class NoteListViewModel constructor( .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe { - state.postValue(state.value!!.copy( - noteList = emptyList() - )) + state.postValue( + state.value!!.copy( + noteList = emptyList() + ) + ) } ) } @@ -64,7 +68,27 @@ class NoteListViewModel constructor( } fun onIsCompletedClick(note: NoteEntity) { - // TODO Добавить вызов noteDao для обновления элемента в таблице. + /*compositeDisposable.add( + noteDao.insertNote(note) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe() + )*/ + + /* compositeDisposable.add( + noteDao.updateNote(note) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe() + )*/ + + compositeDisposable.add( + noteDao.setCompleted(note.id, note.isCompleted) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe() + ) + } override fun onCleared() {