Home > Software engineering >  Android: Recyclerview with ItemTouchHelper.Callback flickering on lower items in list
Android: Recyclerview with ItemTouchHelper.Callback flickering on lower items in list

Time:08-03

I am currently trying to implement a RecyclerView list with drag and drop reordering. For this I use the ItemTouchHelper.SimpleCallback

class SoftkeyScreenListReorderHelperCallback(
   private val adapter: SoftkeyScreenListAdapter
) : ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.START or ItemTouchHelper.END, 0) {

    override fun onMove(
        recyclerView: RecyclerView,
        viewHolder: RecyclerView.ViewHolder,
        target: RecyclerView.ViewHolder
    ): Boolean {
        return adapter.itemMoved(viewHolder.bindingAdapterPosition, target.bindingAdapterPosition)
    }

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

My Adapter got the itemMoved() method, which is called in the onMove() method in the callback. Here I just swap the items and notify the adapter about the change.

fun itemMoved(fromPosition: Int, toPosition: Int): Boolean {
    Collections.swap(list, fromPosition, toPosition)
    notifyItemMoved(fromPosition, toPosition)
    return true
}

For my RecyclerView I implemented the following

binding.recyclerview.apply {
    [...] // adapter init
    myAdapter.setHasStableIds(true)
    adapter = myAdapter

    val touchHelper = ItemTouchHelper(SoftkeyScreenListReorderHelperCallback(adapter as SoftkeyScreenListAdapter))
    touchHelper?.attachToRecyclerView(this)

    (itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false

    setHasFixedSize(true)
}

It works, but I always get flickering for the items below (after) the new item position. Assume I have 5 Items {1,2,3,4,5} and want to swap 1 with 3, then 4 and 5 are flickering. 1, 2 and 3 don't.

I already set the recyclerview size fixed, enabled stable ids and disabled animations, but it does not help. Does anyone has a clue what could be the reason for that and how to fix?

CodePudding user response:

try this

recyclerView.getItemAnimator().setChangeDuration(0);

Possibly, you are getting or loading your data from a place or using a library that requires some time. If that is the case, this answer could help

CodePudding user response:

Try this:

After adapter initialization:

adapter.setHasStableIds(true);

In adapter class:

 @Override
    public long getItemId(int position) {
        return itemList.get(position).hashCode();
    }
  • Related