我正在寻找一个图书馆,要点,摘要或最佳做法来帮助我更新我的RecyclerView.Adapter,当我收到一些项目列表,其中一些项目是新添加的,一些已移动,一些已保留,一些已被删除。我不想使用notifyDatasetChanged,因为我希望可以在视觉上移动移动的项目。
我找不到任何东西。所以我最终自己动手做了。
两件事:
1。是否有图书馆,要点,摘要或最佳做法?
2. 你们可以就我的解决方案提供反馈意见吗?太可怕了吗?我能做些什么不同?你会用它吗?
我尝试尽可能地使用我的解决方案。你可以用两种方式;让它将项目放入适配器并更新它,或者它可以返回每个项目的状态列表,以便您自己处理更新。
public class RecyclerViewAdapterItemsUpdatedHelper<T, A extends RecyclerView.Adapter>{
List<T> currentItems;
List<T> newItems;
public RecyclerViewAdapterItemsUpdatedHelper(
List<T> currentItems,
List<T> newItems) {
this.currentItems = currentItems;
this.newItems = newItems;
}
public enum State {
ADDED, MOVED, REMOVED, KEPT
}
public boolean helpMeHandleIt(A adapter) {
log(currentItems, newItems);
boolean moved = false;
boolean added = false;
boolean removed = false;
for (int i = currentItems.size() -1; i > -1; i--) {
if (!newItems.contains(currentItems.get(i))) {
currentItems.remove(i);
adapter.notifyItemRemoved(i);
removed = true;
}
}
for (int i = 0; i < newItems.size(); i++) {
State state;
try {
if (!newItems.get(i).equals(currentItems.get(i))) {
state = currentItems.contains(newItems.get(i)) ? State.MOVED : State.ADDED;
if (state.equals(State.ADDED)) {
currentItems.add(i, newItems.get(i));
adapter.notifyItemInserted(i);
added = true;
} else if (state.equals(State.MOVED)) {
int from = currentItems.indexOf(newItems.get(i));
currentItems.remove(from);
currentItems.add(i, newItems.get(i));
adapter.notifyItemMoved(from, i);
moved = true;
}
}
} catch (IndexOutOfBoundsException e) {
currentItems.add(i, newItems.get(i));
adapter.notifyItemInserted(i);
added = true;
}
}
return moved && !added && !removed;
}
public List<StatusItem> justGiveMeStatus() {
log(currentItems, newItems);
List<StatusItem> statusItems = new ArrayList<>();
for (int i = currentItems.size() -1; i > -1; i--) {
if (!newItems.contains(currentItems.get(i))) {
statusItems.add(new StatusItem(currentItems.get(i), State.REMOVED, i, -1));
}
}
for (int i = 0; i < newItems.size(); i++) {
State state;
try {
if (!newItems.get(i).equals(currentItems.get(i))) {
state = currentItems.contains(newItems.get(i)) ? State.MOVED : State.ADDED;
if (state.equals(State.ADDED)) {
statusItems.add(new StatusItem(newItems.get(i), State.ADDED, -1, i));
} else if (state.equals(State.MOVED)) {
int from = currentItems.indexOf(newItems.get(i));
statusItems.add(new StatusItem(newItems.get(i), State.MOVED, from, i));
}
} else {
statusItems.add(new StatusItem(newItems.get(i), State.KEPT, i, i));
}
} catch (IndexOutOfBoundsException e) {
statusItems.add(new StatusItem(newItems.get(i), State.ADDED, -1, i));
}
}
return statusItems;
}
private void log(List<T> currentItems, List<T> newItems) {
for (T obj :
currentItems) {
Log.i("current item", obj.toString());
}
for (T obj :
newItems) {
Log.i("new item", obj.toString());
}
}
public class StatusItem {
private T item;
private State status;
private int from = -1;
private int to = -1;
public StatusItem(T item, State status) {
this.item = item;
this.status = status;
}
public StatusItem(T item, State status, int from, int to) {
this.item = item;
this.status = status;
this.from = from;
this.to = to;
}
public T getItem() {
return item;
}
public State getStatus() {
return status;
}
public int getFrom() {
return from;
}
public int getTo() {
return to;
}
@Override
public String toString() {
return item.toString() + " | " + status +
" | " + from + " -> " + to;
}
}