RecyclerView - how to update and move an item at the same time

I have a RecyclerView adapter supported by SortedList. If I make changes to an element, it changes the element and repositions it in the list.

I found that if I use notifyItemChanged at the start or end position of an element, this does not seem to have any effect even when combined with notifyItemMoved before or after.

If I use notifyItemMoved , it starts the motion animation correctly, but the view does not change and still displays outdated information.

If I use notifyDatasetChanged , it updates the line and then moves it, but does it sequentially, which is slow, and obviously notifies the entire list, which is not really needed.

Is there a way to combine moving and updating animations? And why does notifyItemChanged do nothing?

+6
source share
3 answers

The RecyclerView.Adapter link says that notifyItemMoved() is just a structural change and therefore will not update the data. notifyItemChanged() , notifyItemChanged() other hand, is called data modification.

When calling notifyItemChanged() it will call RecyclerView#onBindViewHolder() , so it should update your view.

Working approach for me to update and move:

notifyItemChanged(oldPos); notifyItemMoved(oldPos, newPos);

+1
source

Take a look at DiffUtil https://developer.android.com/reference/android/support/v7/util/DiffUtil.html

When you update your dataset in your adapter, you can use this tool to calculate the notifications needed to correctly present a new dataset.

  • Extend DiffUtil.Callback and implement abstract methods (I create a constructor that looks like this:

     public MyDiffCallback(ArrayList<String> oldList, ArrayList<String> newList) { this.oldList = oldList; this.newList = newList; } 

I store oldList and newList in memory so that I can implement:

areItemsTheSame areContentsTheSame getNewListSize getOldListSize

For instance:

 @Override public int getOldListSize() { return oldList.size(); } @Override public int getNewListSize() { return newList.size(); } @Override public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) { return oldList.get(oldItemPosition).equals(newList(newItemPosition)) } @Override public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { return areItemsTheSame(oldItemPosition, newItemPosition); } 

areItemsTheSame : indicates UTIL if the item is moved (marked position) areContentsTheSame : Tells UTIL if the content of the item has changed.

Now you have the updateDataSet method (or whatever you called it!); do something like:

 public updateDataSet(List newDataSet) { // this.dataSet is the old data set / List final MyDiffCallback callback = new MyDiffCallback(this.dataSet, newDataSet); final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(callback); this.dataSet = newDataSet; diffResult.dispatchUpdatesTo(this); //This is the Adapter } 

Hope this helps, Woof

Link: https://medium.com/@iammert/using-diffutil-in-android-recyclerview-bdca8e4fbb00#.yhxirkkq6

0
source

You can use:

 SortedList.updateItemAt(int position, Objet newItem) 

newItem is the updated item, and position is the current position. This method replaces the current element for newItem and rearranges it in the list (and the recyclerview link).

Here is the official documentation.

Hope this helps you.

0
source

Source: https://habr.com/ru/post/1015504/


All Articles