我想要两件事:
- 当我删除 RecyclerView 中的项目时不重新加载/刷新适配器(不使用
notifyDatasetChanged
)。 - 为此,我正在使用 DiffUtils,它工作得非常好。但我也想保留对
DefaultItemAnimator
DiffUtilsRecyclerView
显然没有影响的 。
所以我的问题是:如何在不刷新所有数据集的情况下删除/更新项目并保持与该项目类似的动画DefaultItemAnimator
?
我知道很多帖子都给出了答案,RecyclerView
但没有一个符合我的需求。我知道notifyItemRemoved
,notifyItemRangeChanged
但他们也刷新了所有数据集。
谢谢
编辑提供一些代码以便更好地理解:
在我的适配器中,我做了两种方法:这就是我在特定位置删除视图的方式。
// 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());
}
这也适用于动画,但刷新了所有其他项目。