Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android kotlin-按特定顺序删除项目后RecyclerView应用程序崩溃_Java_Android_Android Recyclerview_Kotlin - Fatal编程技术网

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之后就尝试过了,但仍然用代码来快速更新答案。请尝试一下,让我知道谢谢我犯了这个错误,现在我的适配器工作正常。你能说出位置和支架的区别吗?它们不应该是一样的吗?