簡體   English   中英

Android Kotlin-按特定順序刪除項目后,RecyclerView應用程序崩潰

[英]Android kotlin - RecyclerView app crash after deleting items in specific order

這是適配器:

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)

可能是什么問題呢?

提前致謝

正如你所看到的,它是一個IndexOutOfBoundsException ,因為你正試圖訪問索引1尺寸1的陣列這主要是因為你直接使用position從參數onBindViewHolder從AlertDialog的內部setPositiveButton電話。

而是使用holder.getAdapterPosition方法來獲取最新位置。 這樣可以防止崩潰。

編輯#1 :我的意思是將position用法替換為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個項目進行測試,當我刪除第二個然后第一個就可以了,但是當第一個然后第二個被刪除時應用程序崩潰了。

我的猜測是您不會刷新列表中項目的索引。當刪除拳頭項目時,一切都很好,您從列表2中刪除了索引0,但是第二次崩潰是因為您嘗試刪除索引1(第二項) )僅剩一個元素的列表。

您的“ notifyItemRemoved(position)”必須重新分配刪除一項后剩余的所有項目的欠款

首先,將click偵聽器設置在bindview持有人之外,因為這是不好的做法。 只需在onCreateViewHolder上進行設置即可。 然后,您將知道,一旦設置了適配器,便會首次調用該偵聽器。 為此,您需要通過簡單地聲明一個bool變量並將它在適配器類中分配為false來阻止它被調用。

 private var islistenerCalledFirst: Boolean = false;

然后在OnCreateViewHolder中設置偵聽器。 注意,您可以通過調用viewHolder.getAdapterPosition()來獲得項目的位置。

  holder.remove.setOnClickListener {

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

        islistenerCalledFirst = true
    }

希望這對您有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM