【问题标题】:Deleting an item in recycler view duplicates the other item在回收站视图中删除一个项目会复制另一个项目
【发布时间】:2019-11-07 13:18:13
【问题描述】:

我使用Room 作为database 并在RecyclerView 中列出数据。当我尝试删除其中一个项目时,它下面的项目会被复制。

但是当我重新启动应用程序时,重复的项目也会被删除(以及我之前删除的项目)。 我试过使用notifyItemRemoved(position),但还是不行。

class HomeFragment : Fragment() {

    private inner class NoteViewHolder(view: View):RecyclerView.ViewHolder(view) {
       val rowName:TextView = view.findViewById(R.id.rec_name)
       val rowType:TextView = view.findViewById(R.id.rec_type)
       val rowSub:TextView = view.findViewById(R.id.rec_sub)
       val daysAgo:TextView = view.findViewById(R.id.how_many_days_ago)
}

private inner class NotesAdapter(val users:List<User>):RecyclerView.Adapter<NoteViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NoteViewHolder {
        val view = layoutInflater.inflate(R.layout.row_recycle, parent, false)
        return  NoteViewHolder(view)
    }

    override fun getItemCount(): Int =users.size

    override fun onBindViewHolder(holder: NoteViewHolder, position: Int) {
        val user = users[position]
        holder.apply{
            rowName.setText(user.name)
            rowSub.setText(user.subject)
            rowType.setText(user.type)
        }

        //To delete
        holder.itemView.setOnLongClickListener {

            val builder = AlertDialog.Builder(requireContext(),R.style.Theme_AppCompat_Light_Dialog_Alert)
            builder.setTitle("Notes Returned?")
            builder.setNegativeButton("Yes",object :DialogInterface.OnClickListener {
                override fun onClick(dialog: DialogInterface?, which: Int) {
                    (activity as MainActivity).db.myDao().deleteData(users[position])
                    notifyItemRemoved(position)
                }
            })
            val alert = builder.create()
            alert.show()
            true
        }
    }
}

MyDao

@Dao
interface MyDao {
    @Delete
    fun deleteData(user: User)
}

User.kt

@Entity
data class User(
    val subject:String,
    val type:String,
    val name: String?,
    val date: String?
)

Mainactivity.kt

lateinit var db: Database
db = Room.databaseBuilder(this,Database::class.java,"User").allowMainThreadQueries().build()

我该如何解决这个问题?

【问题讨论】:

    标签: android kotlin android-recyclerview android-room


    【解决方案1】:

    先从列表中删除,然后调用notifyItemRemoved。检查下面。

    override fun onClick(dialog: DialogInterface?, which: Int) {
        (activity as MainActivity).db.myDao().deleteData(users[position])
    
        users.removeAt(position) // Delete from list
        notifyItemRemoved(position)
    }
    

    注意:您的列表应该是 MutableList 而不是 List 才能执行操作。

    【讨论】:

    • (activity as MainActivity).db.myDao().deleteData(users[position]) 此行从数据库中删除
    • 是的,但不在您当前附加到 RecyclerView 的列表中
    • 它会在重启后显示正确的数据,因为在重启期间它会从DB 获取数据并更新列表。试试我的解决方案并检查
    • 我找不到removeAt 方法。
    • 然后试试users.remove(position)
    【解决方案2】:

    在您的 NoteViewHolder 中,执行以下操作:

    init {
        view.setOnLongClickListener {
            val builder = AlertDialog.Builder(
                requireContext(),
                R.style.Theme_AppCompat_Light_Dialog_Alert
            )
            builder.setTitle("Notes Returned?")
            builder.setNegativeButton("Yes") { dialog, _ ->
                dialog.dismiss()
                context.db.myDao().deleteData(users[adapterPosition])
                notifyItemRemoved(adapterPosition)
            }
            val alert = builder.create()
            alert.show()
            true
        }
    }
    

    全景

    private inner class NoteViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    
        val rowName: TextView = view.findViewById(R.id.rec_name)
        val rowType: TextView = view.findViewById(R.id.rec_type)
        val rowSub: TextView = view.findViewById(R.id.rec_sub)
        val daysAgo: TextView = view.findViewById(R.id.how_many_days_ago)
    
        init {
            view.setOnLongClickListener {
                val builder = AlertDialog.Builder(
                    requireContext(),
                    R.style.Theme_AppCompat_Light_Dialog_Alert
                )
                builder.setTitle("Notes Returned?")
                builder.setNegativeButton("Yes") { dialog, _ ->
                    dialog.dismiss()
                    context.db.myDao().deleteData(users[adapterPosition])
                    notifyItemRemoved(adapterPosition)
                }
                val alert = builder.create()
                alert.show()
                true
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多