-1

I tried this in Kotli, it works fine for the last element but not working properly for middle elements.

 var dltItem = findViewById<Button>(R.id.deleteitem)
    dltItem.setOnClickListener(View.OnClickListener {

        for (i in 0..users.size-1) {
            println("User List Size --> " + users.size)

            if (users[i].isChecked) {
                    users.removeAt(i)
                    Char--

            }
        }

        adapter.notifyDataSetChanged()
    })

It is showing the error when I attempt to delete the middle element.

2021-06-24 20:33:32.272 1755-1755/com.example.gamedemokotlin E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.gamedemokotlin, PID: 1755
java.lang.IndexOutOfBoundsException: Index: 3, Size: 2
    at java.util.ArrayList.get(ArrayList.java:437)
    at com.example.gamedemokotlin.MainActivity$onCreate$2.onClick(MainActivity.kt:49)
    at android.view.View.performClick(View.java:7184)
    at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
    at android.view.View.performClickInternal(View.java:7157)
    at android.view.View.access$3500(View.java:821)
    at android.view.View$PerformClick.run(View.java:27654)
    at android.os.Handler.handleCallback(Handler.java:883)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:224)
    at android.app.ActivityThread.main(ActivityThread.java:7561)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995)

My Model Class

data class TodolistModel(val task_no: Int, val task: String, var isChecked: Boolean)

Adapter

class TodoAdaper(val userList: ArrayList<TodolistModel>) : RecyclerView.Adapter<TodoAdaper.ViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoAdaper.ViewHolder {
    val v = LayoutInflater.from(parent.context).inflate(R.layout.row_list, parent, false)
    return ViewHolder(v)
}

//this method is binding the data on the list
override fun onBindViewHolder(holder: TodoAdaper.ViewHolder, position: Int) {

    val model = userList[position]

    holder.tvTask.text = model.task;
    holder.tvId.text = model.task_no.toString()
    holder.checkBox.isChecked = model.isChecked

    holder.checkBox.setOnClickListener(View.OnClickListener {
        val checkBox = it as CheckBox
        model.isChecked = checkBox.isChecked
        userList[position] = model
        notifyDataSetChanged()
    })

}

//this method is giving the size of the list
override fun getItemCount(): Int {
    return userList.size
}



//the class is hodling the list view
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    lateinit var tvId: TextView
    lateinit var tvTask: TextView
    lateinit var checkBox: CheckBox
    init {
         tvId = itemView.findViewById(R.id.tvId) as TextView
         tvTask  = itemView.findViewById(R.id.tvTask) as TextView
         checkBox = itemView.findViewById(R.id.cbDone) as CheckBox
        
    }
}

When I attempting to delete this then, It is showing error. enter image description here

Note: working fine for the last element.

Machavity
  • 30,841
  • 27
  • 92
  • 100

2 Answers2

1

In addition to @Alex.T's answer

You can also use

users.removeAll { it.checked() }

Because removeif() is only available for API 24+

and don't forget to remove for loop.

Though there is some issue like thread-safe or not. If you want you can check this Use cases of removeall and removeif

Rafiul
  • 1,560
  • 7
  • 19
0

You have a lot of Kotlin concepts quite wrong, I strongly suggest you have a read through the docs and see what methods the standard library objects have. For example not only that your for loop is completely redundant, but also you are also using it wrong.

This is how you remove based on a condition, no need to loop through a range:

users.removeIf { it.isChecked }
AlexT
  • 2,524
  • 1
  • 11
  • 23