Java Android kotlin-按特定顺序删除项目后RecyclerView应用程序崩溃
这是适配器:Java Android kotlin-按特定顺序删除项目后RecyclerView应用程序崩溃,java,android,android-recyclerview,kotlin,Java,Android,Android Recyclerview,Kotlin,这是适配器: class ContactsAdapter(val context: Context, private val users: MutableList<Contacts>, val itemClick: (Contacts) -> Unit) : RecyclerView.Adapter<ContactsAdapter.ViewHolder>(){ override fun onBindViewHolder(holder: ViewHolder
class ContactsAdapter(val context: Context, private val users: MutableList<Contacts>, val itemClick: (Contacts) -> Unit) : RecyclerView.Adapter<ContactsAdapter.ViewHolder>(){
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.remove.setOnClickListener {
val builder = AlertDialog.Builder(context)
builder.setMessage(R.string.delete_contact)
builder.setPositiveButton(R.string.yes){_, _ ->
users.removeAt(position)
notifyItemRemoved(position)
}
builder.setNegativeButton(R.string.no){_,_ ->
}
val dialog: AlertDialog = builder.create()
dialog.show()
}
}
override fun getItemCount() = users.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.contacts, parent, false)
return ViewHolder(view, itemClick)
}
class ViewHolder(itemView: View?, val itemClick: (Contacts) -> Unit) : RecyclerView.ViewHolder(itemView!!){
val remove = itemView!!.removecontact!!
}
}
有什么问题吗
如您所见,这是一个IndexOutOfBoundsException,因为您试图访问大小为1的数组中的索引1。这主要是因为您正在AlertDialog的setPositiveButton调用中直接使用onBindViewHolder的position参数
而是使用holder.getAdapterPosition方法获取最新位置。这应该可以防止撞车
编辑1:我的意思是用holder.getAdapterPosition替换位置用法。编辑后,onBindViewHolder的外观应如下所示:
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.remove.setOnClickListener {
val builder = AlertDialog.Builder(context)
builder.setMessage(R.string.delete_contact)
builder.setPositiveButton(R.string.yes){_, _ ->
users.removeAt(holder.getAdapterPosition())
notifyItemRemoved(holder.getAdapterPosition())
}
builder.setNegativeButton(R.string.no){_,_ ->
}
val dialog: AlertDialog = builder.create()
dialog.show()
}
}
如您所见,这是一个IndexOutOfBoundsException,因为您试图访问大小为1的数组中的索引1。这主要是因为您正在AlertDialog的setPositiveButton调用中直接使用onBindViewHolder的position参数
而是使用holder.getAdapterPosition方法获取最新位置。这应该可以防止撞车
编辑1:我的意思是用holder.getAdapterPosition替换位置用法。编辑后,onBindViewHolder的外观应如下所示:
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.remove.setOnClickListener {
val builder = AlertDialog.Builder(context)
builder.setMessage(R.string.delete_contact)
builder.setPositiveButton(R.string.yes){_, _ ->
users.removeAt(holder.getAdapterPosition())
notifyItemRemoved(holder.getAdapterPosition())
}
builder.setNegativeButton(R.string.no){_,_ ->
}
val dialog: AlertDialog = builder.create()
dialog.show()
}
}
我有两个测试项目,当我删除第二个,然后第一个,这是很好的,但当第一个,然后第二个,然后应用程序崩溃
我猜您不会刷新视图中列表项的索引
当您删除第一个项目时,一切正常,您从2的列表中删除了索引0
但是您的第二个崩溃是因为您试图删除索引1—列表中只剩下一个元素的第二项
您的notifyItemRemovedposition必须重新分配删除一个项目后剩下的所有项目的索引
我有两个测试项目,当我删除第二个,然后第一个,这是很好的,但当第一个,然后第二个,然后应用程序崩溃
我猜您不会刷新视图中列表项的索引
当您删除第一个项目时,一切正常,您从2的列表中删除了索引0
但是您的第二个崩溃是因为您试图删除索引1—列表中只剩下一个元素的第二项
您的notifyItemRemovedposition必须重新分配删除一个项目后剩下的所有项目的索引。首先,将click listener设置在bindview持有者之外,因为这是一种不好的做法。只需将其设置为onCreateViewHolder。然后,您就会知道,一旦设置了适配器,侦听器就会第一次被调用。为此,您需要通过在适配器类中声明一个bool变量并将其赋值为false来阻止调用它,如下所示
private var islistenerCalledFirst: Boolean = false;
然后在OnCreateViewHolder中设置侦听器。注意,您可以通过调用viewHolder.getAdapterPosition获取项目的位置
holder.remove.setOnClickListener {
if(islistenerCalledFirst){
... //your logic
}
islistenerCalledFirst = true
}
希望这对您有用。首先,将单击侦听器设置在bindview保持架之外,因为这是一种不好的做法。只需将其设置为onCreateViewHolder。然后,您就会知道,一旦设置了适配器,侦听器就会第一次被调用。为此,您需要通过在适配器类中声明一个bool变量并将其赋值为false来阻止调用它,如下所示
private var islistenerCalledFirst: Boolean = false;
然后在OnCreateViewHolder中设置侦听器。注意,您可以通过调用viewHolder.getAdapterPosition获取项目的位置
holder.remove.setOnClickListener {
if(islistenerCalledFirst){
... //your logic
}
islistenerCalledFirst = true
}
希望这对您有用。当您删除第一项时,第二项的位置从1变为0,因此出现错误。这就是我刚才想的,但如何解决这个问题?而不是这样:NotifyItemRemovePosition尝试notifyDataSetChangedNope同样的情况而不是position尝试在这三行中尝试getAdapterPosition。当您删除第一项时,第二个项目的位置从1变为0,因此出现错误。这就是我刚才所想的,但如何解决此问题?而不是:NotifyItemRemovePosition尝试notifyDataSetChangedNope相同的情况而不是position在这三行中尝试getAdapterPosition。您能演示如何解决此问题吗?我不理解所有这些预构建的东西,我在users.removeAtposition之后就尝试过了,但仍然用代码来快速更新答案。请尝试一下,让我知道谢谢我犯了这个错误,现在我的适配器工作正常。你能说出位置和支架的区别吗?它们不应该是一样的吗?你能告诉我怎么做吗?我不理解所有这些预构建的东西,我在users.removeAtposition之后就尝试过了,但仍然用代码来快速更新答案。请尝试一下,让我知道谢谢我犯了这个错误,现在我的适配器工作正常。你能说出位置和支架的区别吗?它们不应该是一样的吗?