如何在 Kotlin 中使用 LiveData 和 RoomDatabase 在 RecyclerView 中实现 ItemTouchHelper

如何解决如何在 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)
        }
    })

这里是 viewmodel.kt 中的更新内容

   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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?