如何解决如何在 Kotlin 中使用 LiveData 和 RoomDatabase 在 RecyclerView 中实现 ItemTouchHelper
我现在解决这个问题已经一个多星期了,无论我阅读了多少文档和帖子,或者我在代码中尝试了什么,我都无法在这方面取得任何进展。这似乎是一个特殊的问题,但我认为最初的情况很简单。所以我最后一次尝试是寻求你们的帮助。
我只想在使用 Room 数据库中的 livedata 的 recyclerview 上实现 simpleItemTouchCallback。这是我写的一个小noteapp,只是为了学习android,所以我现在是一个noob。
我的问题是,第一次拖放操作完全正常。该应用程序更改数据库条目的 ID 没问题。但是,如果我第二次拖动,该应用程序将通过无限地交换两个音符而停止并翻转。如果我再丢掉其他人,一些笔记会被其他人覆盖,一切都完全混乱。似乎 Touchcallbacker 并没有停止按预期更新一次 note-ID 的程序化操作。
我遵循 MVVM 模型,并且我有一个使用 viewmodel 的 Fragment。在片段中,我在 Room Database 上设置了一个观察者并将其与 ItemTouchCallback 连接:
片段.kt:
// Setting layoutManager and bind it to databinding
val layoutManagerNotes = object : GridLayoutManager(
activity,numberOfRows,HORIZONTAL,false
) {
override fun checkLayoutParams(layoutParams: RecyclerView.LayoutParams): Boolean {
layoutParams.width = width / numberOfColumns
return true
}
}
binding.recyclerViewNotes.layoutManager = layoutManagerNotes
// get the Adapter and connect it and then observe the notes
val adapterNotes = NotesAdapter()
binding.recyclerViewNotes.adapter = adapterNotes
mainviewmodel.allNotes.observe(viewLifecycleOwner,{
it?.let {
adapterNotes.submitList(it)
}
})
// Setting the itemtouchhelper
mainviewmodel.allNotes.observe(viewLifecycleOwner,{
it.let {
val simpleItemTouchCallback =
object : itemtouchhelper.SimpleCallback(
UP or DOWN or START or END,0) {
var fromValue: Int = 0
override fun onSwiped(viewHolder: RecyclerView.ViewHolder,direction: Int
) {}
override fun onSelectedChanged(
viewHolder: RecyclerView.ViewHolder?,actionState: Int
) {
super.onSelectedChanged(viewHolder,actionState)
if (actionState == ACTION_STATE_DRAG) {
viewHolder?.itemView?.alpha = 0.5f
}
}
override fun onMove(recyclerView: RecyclerView,viewHolder: RecyclerView.ViewHolder,target: RecyclerView.ViewHolder
): Boolean {
val from = viewHolder.adapterPosition
val to = target.adapterPosition
// I store the from value to later in clearView write the value to the database
fromValue = from
Collections.swap(it,from,to)
adapterNotes.notifyItemmoved(from,to)
adapterTitles.notifyItemmoved(from,to)
return true
}
override fun clearView(
recyclerView: RecyclerView,viewHolder: RecyclerView.ViewHolder
) {
val to = viewHolder.adapterPosition
super.clearView(recyclerView,viewHolder)
viewHolder.itemView.alpha = 1.0f
// here comes the viewmodel update method
mainviewmodel.updateNote(it[fromValue],it[to])
}
}
itemtouchhelper(simpleItemTouchCallback).attachToRecyclerView(binding.recyclerViewNotes)
}
})
private suspend fun update(note: NoteEntry) {
withContext(dispatchers.IO) {
dataSource.updateNote(note)
}
}
fun updateNote(noteFrom: NoteEntry,noteto: NoteEntry) {
viewmodelScope.launch {
val swapNotes = noteFrom.noteId
noteFrom.noteId = noteto.noteId
noteto.noteId = swapNotes
update(noteFrom)
update(noteto)
}
}
和 DAO
@Update
suspend fun updateNote(note: NoteEntry)
我用 dao 做了很多实验,比如也许可以有一个方法来更新整个列表,或者这样,但没有成功。我还读到,可能无法交换自动生成的 ID(主键),但我不这么认为,因为正如我所说,第一次交换工作正常。
如果你能以某种方式帮助我,我会很高兴。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。