Мне бы хотелось две вещи:
- Чтобы не перезагружать / не обновлять sh адаптер, когда я удаляю элемент внутри RecyclerView (без использования
notifyDatasetChanged
). - Для этого я использую DiffUtils, который прекрасно работает. Но я также хотел бы сохранить
DefaultItemAnimator
из RecyclerView
, который, по-видимому, не влияет на DiffUtils.
Поэтому мой вопрос: как я могу удалить / обновить элемент, не обновляя все набор данных И сохраняйте анимацию, аналогичную DefaultItemAnimator
?
Я знаю, что многие посты дают ответы о RecyclerView
, но ни один из них не соответствует моим потребностям. Я знаю о notifyItemRemoved
, notifyItemRangeChanged
, но они также обновляют sh весь набор данных.
Спасибо
EDIT , дающие некоторый код для лучшего понимания :
В моем адаптере я сделал два метода: Вот так я удаляю свое представление в указанной позиции c.
// Adapter methods
void removeAt(int position) {
dataList.remove(position);
recyclerView.removeViewAt(position);
updateList(dataList);
}
void updateList(ArrayList<MyModel> newList) {
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffUtilsTheme(oldList, newList));
diffResult.dispatchUpdatesTo(this);
}
А вот мой класс DiffUtils:
public class DiffUtils extends DiffUtil.Callback{
ArrayList<MyModel> oldItems;
ArrayList<MyModel> newItems;
public DiffUtils(ArrayList<MyModel> newItems, ArrayList<MyModel> oldItems) {
this.newItems = newItems;
this.oldItems = oldItems;
}
/**
* It returns the size of the old list.
* @return
*/
@Override
public int getOldListSize() {
return oldItems.size();
}
/**
* Returns the size of the new list;
* @return
*/
@Override
public int getNewListSize() {
return newItems.size();
}
/**
* Called by the DiffUtil to decide whether two object represent the same Item.
* Here we check the names because we know they are unique.
* @param oldItemPosition
* @param newItemPosition
* @return
*/
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
// We are sure that the names are unique
return oldItems.get(oldItemPosition).getItemName().equals(newItem.get(newItemPosition).getItemName());
}
/**
* Checks whether two items have the same data.
* This method is called by DiffUtil only if areItemsTheSame returns true.
* @param oldItemPosition
* @param newItemPosition
* @return
*/
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return oldItems.get(oldItemPosition).equals(newItems.get(newItemPosition));
}
/**
* If areItemTheSame return true and areContentsTheSame returns false DiffUtil calls this method to get a payload about the change.
* @param oldItemPosition
* @param newItemPosition
* @return
*/
@Nullable
@Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
return super.getChangePayload(oldItemPosition, newItemPosition);
}
}
Это удаляет элемент из списка, но без анимации. Мой RecyclerView
также имеет ItemAnimator
:
recyclerView.setItemAnimator(new DefaultItemAnimator());
Перед использованием класса DiffUtils
я удалял вот так:
void removeAt(int position) {
dataList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, dataList.size());
}
Какой также работал и с анимацией, но обновлял все остальные элементы.