I am building a component based on RecyclerView, allowing user to reorder items by drag and drop. Once I am on the DragListener side, I need the position it has in the adapter in order to perform correct move, but I only have access to the view. So here is what I am doing in the adapter view binding :
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
Track track = mArray.get(position);
viewHolder.itemView.setTag(R.string.TAG_ITEM_POSITION, position);
}
Does it seem correct to you ? Because if I move an item like this :
public void move(int from, int to){
Track track = mArray.remove(from);
mArray.add(to, track);
notifyItemMoved(from, to);
}
then position tag is not correct anymore, and if I notifyDataSetChanged(), I lose the fancy animation. Any suggestion ?
There is a way to preserve fancy animations with just notifyDataSetChanged()
You need to make your own GridLayoutManager
with overriden supportsPredictiveItemAnimations()
method returning true
;
You need to mAdapter.setHasStableIds(true)
The part I find tricky is you need to override you adapter's getItemId()
method. It should return value that is truly unique and not a direct function of position
. Something like mItems.get(position).hashCode()
Worked perfectly fine in my case - beautiful animations for adding, removing and moving items only using notifyDataSetChanged()