-1

After i delete an item, the indexes of other items corrupt. If i swipe up and down, the index of items be normal. So if i want my app work properly i have to swipe up and down after delete an item.

Is this a bug? Is there anything i can do?

This is the video i recorded.

https://www.youtube.com/watch?v=UQnaeC6EV70

MainActivity.kt

class MainActivity : AppCompatActivity() {

private var dataset = mutableListOf("Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10",
    "Item 11", "Item 12", "Item 13", "Item 14", "Item 15", "Item 16", "Item 17", "Item 18", "Item 19", "Item 20",
    "Item 21", "Item 22", "Item 23", "Item 24", "Item 25", "Item 26", "Item 27", "Item 28", "Item 29", "Item 30")

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val myAdapter = MyAdapter(dataset, this)
    val itemDecor = DividerItemDecoration(this, HORIZONTAL)
    recyclerView.addItemDecoration(itemDecor)
    recyclerView.layoutManager = LinearLayoutManager(this)
    recyclerView.adapter = myAdapter

    val itemTouchHelperCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT){
        override fun onMove(
            recyclerView: RecyclerView,
            viewHolder: RecyclerView.ViewHolder,
            target: RecyclerView.ViewHolder
        ): Boolean {
            return false
        }

        override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
            myAdapter.removeItem(viewHolder)
        }

    }
    val itemTouchHelper = ItemTouchHelper(itemTouchHelperCallback)
    itemTouchHelper.attachToRecyclerView(recyclerView)
}

}

MyAdapter.kt

class MyAdapter(val arrayList: MutableList<String>, val context: Context) : RecyclerView.Adapter<MyAdapter.ViewHolder>() {

private var removedPosition: Int = 0
private lateinit var removedItem: String

class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){

    fun bindItems(data: String){
        itemView.textBox.text = data
    }
}

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

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    holder.bindItems(arrayList[position])

    holder.itemView.setOnClickListener {
        Toast.makeText(context, arrayList[position], Toast.LENGTH_SHORT).show()
    }
}

override fun getItemCount(): Int {
    return arrayList.size
}

fun removeItem(viewHolder: RecyclerView.ViewHolder){
    removedPosition = viewHolder.adapterPosition
    removedItem = arrayList[removedPosition]

    arrayList.removeAt(removedPosition)
    notifyItemRemoved(removedPosition)
}

}

Ali Mali
  • 1
  • 2

1 Answers1

1

For some reason, nofityItemRemoved only affects the item that is removed and allows all subsequent item numbers to go out of sync. So you need to follow it with a call to notifyItemRangeChanged.

fun removeItem(viewHolder: RecyclerView.ViewHolder){
    removedPosition = viewHolder.adapterPosition
    removedItem = arrayList[removedPosition]

    arrayList.removeAt(removedPosition)
    notifyItemRemoved(removedPosition)
    notifyItemRangeChanged(removedPosition, arrayList.size)
}

This answer on a similar question states that if you do it this way, you get a proper animation of the item being removed, but I haven't tried it:

fun removeItem(viewHolder: RecyclerView.ViewHolder){
    removedPosition = viewHolder.adapterPosition
    removedItem = arrayList[removedPosition]

    arrayList.removeAt(removedPosition)
    notifyItemChanged(removedPosition)
    notifyItemRangeRemoved(removedPosition, 1)
}
Tenfour04
  • 83,111
  • 11
  • 94
  • 154