androidandroid-recyclerviewitemtouchhelper

ItemTouchHelper Item doesnt gets properly removed after long press


I have a problem with a RecyclerView where the element should be removed by clicking: When I attach an ItemTouchHelper to the RecyclerView to drag and drop items into the list, and long press an item without dragging it to a new position, the item is removed from my list and getItemCount returns 0 back, but the element is still visible, it is like it would get pinned. When other items are added it get simply overlaid. The only solution was to set a LongClickListener on the view, which also removes the element when clicked but I dont think this is a good solution. How can I fix this problem?

Video of the bug

My Code:

MainActivtiy:

class MainActivity : AppCompatActivity() {
    @SuppressLint("MissingInflatedId")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val recyclerView = findViewById<RecyclerView>(R.id.recView)
        recyclerView.layoutManager = LinearLayoutManager(this)
        val myAdapter = MyAdapter(layoutInflater,mutableListOf("A","B","C","D","E","F")){items,position->
            items.removeAt(position)
            recyclerView.adapter?.notifyItemRemoved(position)
        }
        recyclerView.adapter =  myAdapter
        val myItemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP or ItemTouchHelper.DOWN,0){
            override fun onMove(
                recyclerView: RecyclerView,
                viewHolder: ViewHolder,
                target: ViewHolder
            ): Boolean {
                val item = myAdapter.items[viewHolder.adapterPosition]
                myAdapter.items.removeAt(viewHolder.adapterPosition)
                myAdapter.items.add(target.adapterPosition,item)
                recyclerView.adapter?.notifyItemMoved(viewHolder.adapterPosition,target.adapterPosition)
                return true
            }

            override fun onSwiped(viewHolder: ViewHolder, direction: Int) {
            }

        })
        myItemTouchHelper.attachToRecyclerView(recyclerView)
    }
}

MyAdapter:

class MyAdapter(val layoutInflater: LayoutInflater, val items: MutableList<String>,val onItemClicked: (items: MutableList<String>,position: Int)->Unit): RecyclerView.Adapter<MyAdapter.MyViewHolder>() {

    class MyViewHolder(view: View): ViewHolder(view){
        val textView = view.findViewById<TextView>(R.id.textview)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        return MyViewHolder(layoutInflater.inflate(R.layout.list_item,parent,false))
    }

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

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.textView.text = items[position]
        holder.textView.setOnClickListener{
            onItemClicked(items,holder.adapterPosition)
        }
    }
}

Solution

  • I solved it by calling holder.setIsRecyclable(true) before notifyItemRemoved()