Android Kotlin-按特定顺序删除项目后,RecyclerView应用程序崩溃

时间:2018-11-02 10:07:54

标签: 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, 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!!
    }
}

我有2个项目要测试,当我删除第二个然后第一个就可以了,但是当第一个然后第二个被删除时,应用崩溃了,错误是:

java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        at java.util.ArrayList.remove(ArrayList.java:503)
        at com.xxx.xxx.classes.ContactsAdapter$onBindViewHolder$2$1.onClick(ContactsAdapter.kt:57)
        at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:177)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6944)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

可能是什么问题?

预先感谢

3 个答案:

答案 0 :(得分:1)

如您所见,它是一个var val = await distributedCache.GetStringAsync(key) ,因为您试图访问大小为1的数组中的索引1。这主要是因为您直接使用了{的IndexOutOfBoundsException参数{1}}来自AlertDialog的position调用中。

请改为使用onBindViewHolder方法来获取最新职位。这样可以防止崩溃。

编辑#1 :我的意思是将setPositiveButton的用法替换为holder.getAdapterPosition。编辑后,您的onBindViewHolder应该如下所示:

position

答案 1 :(得分:0)

  

我有2个项目要进行测试,当我删除第二个然后第一个就可以了,但是当第一个然后第二个被删除时应用崩溃了。

我的猜测是您不会刷新列表中项目的索引 当您删除拳头项目时,一切都很好,您从列表2中删除了索引0 但是第二次崩溃是因为您尝试删除仅剩一个元素的列表的索引1(第二项)。

您的“ notifyItemRemoved(position)”必须重新分配删除一个项目后剩下的所有项目的欠款

答案 2 :(得分:0)

首先,将click侦听器设置在bindview持有人之外,因为这是不良做法。只需在onCreateViewHolder上进行设置即可。然后,您将知道,一旦设置了适配器,便会首次调用该侦听器。为此,您需要通过简单地声明一个bool变量并将其在适配器类中分配为false来阻止它被调用。

 private var islistenerCalledFirst: Boolean = false;

然后在OnCreateViewHolder中设置侦听器。请注意,您可以通过调用viewHolder.getAdapterPosition()来获得商品的位置。

  holder.remove.setOnClickListener {

        if(islistenerCalledFirst){
              ... //your logic
        }

        islistenerCalledFirst = true
    }

希望这对您有用。