1

RecyclerView after delete any item lift bottom item up and redraw it at the same time. It looks strange. How can i solve this problem? (how it looks https://youtu.be/hKmNWwfxfzM !)

val swipeHandler = object : SwipeToDeleteCallback(requireContext()) {
            override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
                viewModel.deleteNote(viewModel.noteListLiveData.value!![viewHolder.adapterPosition])
            }
        }
        val itemTouchHelper = ItemTouchHelper(swipeHandler)
        itemTouchHelper.attachToRecyclerView(binding.noteRecyclerView)

Use LiveData to update RV

viewModel.noteListLiveData.observe(
            viewLifecycleOwner, { notes -> noteAdapter.submitList(notes) }
        )

DiffUtil and Adapter

 private inner class DiffCallback : DiffUtil.ItemCallback<NoteEntity>() {
        override fun areItemsTheSame(oldItem: NoteEntity, newItem: NoteEntity): Boolean {
            return oldItem.id == newItem.id
        }

        override fun areContentsTheSame(oldItem: NoteEntity, newItem: NoteEntity): Boolean {
            return oldItem == newItem
        }
    }

    private inner class NoteAdapter :
        ListAdapter<NoteEntity, NoteHolder>(DiffCallback()) {

        override fun getItemCount(): Int {
            return super.getItemCount()
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NoteHolder {
            val view = layoutInflater.inflate(R.layout.list_item_note, parent, false)
            return NoteHolder(view)
        }

        override fun onBindViewHolder(holder: NoteHolder, position: Int) {
            holder.bind(getItem(position))
        }
    }

I have been looking for a solution to the problem for a long time, but I could not understand what the reason is

sorry for my bad english, it's not my native language

kivinus
  • 15
  • 2

2 Answers2

2

I had the same exact problem and it was caused by using wrap_content for RecyclerView in your xml file.

Because you delete an item, the size of this view changes, and for a split second you can see this weird behaviour. To fix that, make sure that the RecyclerView occupies the whole screen - its height is set to match_parent and the container it is in is also set to match_parent.

baltekg
  • 985
  • 9
  • 31
  • 1
    Nice answer! .. Apart from the issue, using `wrap_content` for `RecyclerView` is not a good practice int terms of performance as it has new calculations for the entire list of the `RecyclerView` whenever adding/removing rows and this makes it lose its main feature for recycling views in this case – Zain May 01 '21 at 10:49
  • 1
    That is a valid point Zain. I am just wondering if `wrap_content` would cause trouble if `hasFixedSize` is set to true? From my understanding if `wrap_content` is a necessity in some case, setting this flag to true might help with performance issues caused by using `wrap_content`. – baltekg May 03 '21 at 16:59
  • Nice catch indeed.. [this answer](https://stackoverflow.com/questions/28709220/understanding-recyclerview-sethasfixedsize#59033210) has a clue, but I think you need to test it your self with a simple example, you could extend the `layoutManger` and debug it to see which methods can be called in either case – Zain May 03 '21 at 21:58
0

Sorry. Strange behavior was not caused by the adapter but by xml. Height of the layout was set as wrap_content and after removing the item size of RV changed which caused the wrong behavior.

kivinus
  • 15
  • 2