Im using Recycler View with data Binding to display a list of Routes. For Testing there are always (and only) 10 Items (Route1 -10) Every Route has a delete Button, to delete the Row the User picked(From the List and from the RV). When deleting the first or second Item without scrolling, it works just fine and I can delete all Items. But After scrolling, (I think) the Adapter sets the Position to a wrong value and deletes the wrong items. Eventually the program crashes with a IndexOutOfBoundsException.
I tried to use other positions instead of the int position i get from the Adapter:
holder.absoluteAdapterPosition holder.adapterPosition holder.bindingAdapterPosition holder.layoutPosition
Unfortunately it didnt change the outcome.
Then I tried: Kotlin RecyclerView delete item. Is this a bug? Works better, but after deleting the last item of the List the adapter position is corrupt again.
Finnaly I wrote the onClicklistener for the delete Button inside the View Holder of my Adapter. Now it works, but I dont understand why. Can someone please explain me this behavior?
package com.example.testnestedxml
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.testnestedxml.databinding.ListItemBinding
class RouteAdapter(
private var routeList: ArrayList<Route>
) :
RecyclerView.Adapter<RouteViewHolder>() {
//Fügt alle Items (Views) in eine View
private lateinit var binding: ListItemBinding
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RouteViewHolder {
//View wird erstellt
binding = ListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return RouteViewHolder(binding)
}
override fun onBindViewHolder(holder: RouteViewHolder, position: Int) {
val route = routeList[position]
holder.routeViewHolderBinding(route, routeList,this)
}
override fun getItemCount(): Int = routeList.size
}
package com.example.testnestedxml
import android.content.Intent
import android.os.Handler
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.RecyclerView
import com.example.testnestedxml.databinding.ListItemBinding
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import java.lang.reflect.Type
class RouteViewHolder(
private val binding: ListItemBinding,
) : RecyclerView.ViewHolder(binding.root) {
fun routeViewHolderBinding(
route: Route,
routeList: ArrayList<Route>,
routeAdapter: RouteAdapter
) {
binding.name.text = route.name
binding.dauer.text = route.duration.toString()
binding.entfernung.text = route.length.toString()
val itemPosition = layoutPosition
binding.delete.setOnClickListener {
routeList.removeAt(itemPosition)
routeAdapter.notifyDataSetChanged()
saveDataRouteAdapter(routeList)
}
}
private fun saveDataRouteAdapter(routeList: ArrayList<Route>) {
val sharedPreferences = binding.root.context.getSharedPreferences(
"shared preferences",
AppCompatActivity.MODE_PRIVATE
)
val editor = sharedPreferences.edit()
val gson = Gson()
val json = gson.toJson(routeList)
editor.putString("Route list", json)
editor.apply()
}
}