604 lines
21 KiB
Java
604 lines
21 KiB
Java
|
package androidx.recyclerview.widget;
|
||
|
|
||
|
import androidx.core.util.Pools;
|
||
|
import androidx.recyclerview.widget.OpReorderer;
|
||
|
import androidx.recyclerview.widget.RecyclerView;
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.Collections;
|
||
|
import java.util.List;
|
||
|
public class AdapterHelper implements OpReorderer.Callback {
|
||
|
private static final boolean DEBUG = false;
|
||
|
public static final int POSITION_TYPE_INVISIBLE = 0;
|
||
|
public static final int POSITION_TYPE_NEW_OR_LAID_OUT = 1;
|
||
|
private static final String TAG = "AHT";
|
||
|
public final Callback mCallback;
|
||
|
public final boolean mDisableRecycler;
|
||
|
private int mExistingUpdateTypes;
|
||
|
public Runnable mOnItemProcessedCallback;
|
||
|
public final OpReorderer mOpReorderer;
|
||
|
public final ArrayList<UpdateOp> mPendingUpdates;
|
||
|
public final ArrayList<UpdateOp> mPostponedList;
|
||
|
private Pools.Pool<UpdateOp> mUpdateOpPool;
|
||
|
|
||
|
public interface Callback {
|
||
|
RecyclerView.ViewHolder findViewHolder(int i);
|
||
|
|
||
|
void markViewHoldersUpdated(int i, int i2, Object obj);
|
||
|
|
||
|
void offsetPositionsForAdd(int i, int i2);
|
||
|
|
||
|
void offsetPositionsForMove(int i, int i2);
|
||
|
|
||
|
void offsetPositionsForRemovingInvisible(int i, int i2);
|
||
|
|
||
|
void offsetPositionsForRemovingLaidOutOrNewView(int i, int i2);
|
||
|
|
||
|
void onDispatchFirstPass(UpdateOp updateOp);
|
||
|
|
||
|
void onDispatchSecondPass(UpdateOp updateOp);
|
||
|
}
|
||
|
|
||
|
public static class UpdateOp {
|
||
|
public static final int ADD = 1;
|
||
|
public static final int MOVE = 8;
|
||
|
public static final int POOL_SIZE = 30;
|
||
|
public static final int REMOVE = 2;
|
||
|
public static final int UPDATE = 4;
|
||
|
public int cmd;
|
||
|
public int itemCount;
|
||
|
public Object payload;
|
||
|
public int positionStart;
|
||
|
|
||
|
public UpdateOp(int i, int i2, int i3, Object obj) {
|
||
|
this.cmd = i;
|
||
|
this.positionStart = i2;
|
||
|
this.itemCount = i3;
|
||
|
this.payload = obj;
|
||
|
}
|
||
|
|
||
|
public String cmdToString() {
|
||
|
int i = this.cmd;
|
||
|
return i != 1 ? i != 2 ? i != 4 ? i != 8 ? "??" : "mv" : "up" : "rm" : "add";
|
||
|
}
|
||
|
|
||
|
public boolean equals(Object obj) {
|
||
|
if (this == obj) {
|
||
|
return true;
|
||
|
}
|
||
|
if (obj == null || getClass() != obj.getClass()) {
|
||
|
return false;
|
||
|
}
|
||
|
UpdateOp updateOp = (UpdateOp) obj;
|
||
|
int i = this.cmd;
|
||
|
if (i != updateOp.cmd) {
|
||
|
return false;
|
||
|
}
|
||
|
if (i == 8 && Math.abs(this.itemCount - this.positionStart) == 1 && this.itemCount == updateOp.positionStart && this.positionStart == updateOp.itemCount) {
|
||
|
return true;
|
||
|
}
|
||
|
if (this.itemCount != updateOp.itemCount || this.positionStart != updateOp.positionStart) {
|
||
|
return false;
|
||
|
}
|
||
|
Object obj2 = this.payload;
|
||
|
if (obj2 != null) {
|
||
|
if (!obj2.equals(updateOp.payload)) {
|
||
|
return false;
|
||
|
}
|
||
|
} else if (updateOp.payload != null) {
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public int hashCode() {
|
||
|
return (((this.cmd * 31) + this.positionStart) * 31) + this.itemCount;
|
||
|
}
|
||
|
|
||
|
public String toString() {
|
||
|
return Integer.toHexString(System.identityHashCode(this)) + "[" + cmdToString() + ",s:" + this.positionStart + "c:" + this.itemCount + ",p:" + this.payload + "]";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public AdapterHelper(Callback callback) {
|
||
|
this(callback, false);
|
||
|
}
|
||
|
|
||
|
public AdapterHelper(Callback callback, boolean z2) {
|
||
|
this.mUpdateOpPool = new Pools.SimplePool(30);
|
||
|
this.mPendingUpdates = new ArrayList<>();
|
||
|
this.mPostponedList = new ArrayList<>();
|
||
|
this.mExistingUpdateTypes = 0;
|
||
|
this.mCallback = callback;
|
||
|
this.mDisableRecycler = z2;
|
||
|
this.mOpReorderer = new OpReorderer(this);
|
||
|
}
|
||
|
|
||
|
private void applyAdd(UpdateOp updateOp) {
|
||
|
postponeAndUpdateViewHolders(updateOp);
|
||
|
}
|
||
|
|
||
|
private void applyMove(UpdateOp updateOp) {
|
||
|
postponeAndUpdateViewHolders(updateOp);
|
||
|
}
|
||
|
|
||
|
private void applyRemove(UpdateOp updateOp) {
|
||
|
char c2;
|
||
|
boolean z2;
|
||
|
int i = updateOp.positionStart;
|
||
|
int i2 = updateOp.itemCount + i;
|
||
|
char c3 = 65535;
|
||
|
int i3 = i;
|
||
|
int i4 = 0;
|
||
|
while (i3 < i2) {
|
||
|
if (this.mCallback.findViewHolder(i3) != null || canFindInPreLayout(i3)) {
|
||
|
if (c3 == 0) {
|
||
|
dispatchAndUpdateViewHolders(obtainUpdateOp(2, i, i4, null));
|
||
|
z2 = true;
|
||
|
} else {
|
||
|
z2 = false;
|
||
|
}
|
||
|
c2 = 1;
|
||
|
} else {
|
||
|
if (c3 == 1) {
|
||
|
postponeAndUpdateViewHolders(obtainUpdateOp(2, i, i4, null));
|
||
|
z2 = true;
|
||
|
} else {
|
||
|
z2 = false;
|
||
|
}
|
||
|
c2 = 0;
|
||
|
}
|
||
|
if (z2) {
|
||
|
i3 -= i4;
|
||
|
i2 -= i4;
|
||
|
i4 = 1;
|
||
|
} else {
|
||
|
i4++;
|
||
|
}
|
||
|
i3++;
|
||
|
c3 = c2;
|
||
|
}
|
||
|
if (i4 != updateOp.itemCount) {
|
||
|
recycleUpdateOp(updateOp);
|
||
|
updateOp = obtainUpdateOp(2, i, i4, null);
|
||
|
}
|
||
|
if (c3 == 0) {
|
||
|
dispatchAndUpdateViewHolders(updateOp);
|
||
|
} else {
|
||
|
postponeAndUpdateViewHolders(updateOp);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void applyUpdate(UpdateOp updateOp) {
|
||
|
int i = updateOp.positionStart;
|
||
|
int i2 = updateOp.itemCount + i;
|
||
|
int i3 = i;
|
||
|
char c2 = 65535;
|
||
|
int i4 = 0;
|
||
|
while (i < i2) {
|
||
|
if (this.mCallback.findViewHolder(i) != null || canFindInPreLayout(i)) {
|
||
|
if (c2 == 0) {
|
||
|
dispatchAndUpdateViewHolders(obtainUpdateOp(4, i3, i4, updateOp.payload));
|
||
|
i3 = i;
|
||
|
i4 = 0;
|
||
|
}
|
||
|
c2 = 1;
|
||
|
} else {
|
||
|
if (c2 == 1) {
|
||
|
postponeAndUpdateViewHolders(obtainUpdateOp(4, i3, i4, updateOp.payload));
|
||
|
i3 = i;
|
||
|
i4 = 0;
|
||
|
}
|
||
|
c2 = 0;
|
||
|
}
|
||
|
i4++;
|
||
|
i++;
|
||
|
}
|
||
|
if (i4 != updateOp.itemCount) {
|
||
|
Object obj = updateOp.payload;
|
||
|
recycleUpdateOp(updateOp);
|
||
|
updateOp = obtainUpdateOp(4, i3, i4, obj);
|
||
|
}
|
||
|
if (c2 == 0) {
|
||
|
dispatchAndUpdateViewHolders(updateOp);
|
||
|
} else {
|
||
|
postponeAndUpdateViewHolders(updateOp);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private boolean canFindInPreLayout(int i) {
|
||
|
int size = this.mPostponedList.size();
|
||
|
for (int i2 = 0; i2 < size; i2++) {
|
||
|
UpdateOp updateOp = this.mPostponedList.get(i2);
|
||
|
int i3 = updateOp.cmd;
|
||
|
if (i3 == 8) {
|
||
|
if (findPositionOffset(updateOp.itemCount, i2 + 1) == i) {
|
||
|
return true;
|
||
|
}
|
||
|
} else if (i3 == 1) {
|
||
|
int i4 = updateOp.positionStart;
|
||
|
int i5 = updateOp.itemCount + i4;
|
||
|
while (i4 < i5) {
|
||
|
if (findPositionOffset(i4, i2 + 1) == i) {
|
||
|
return true;
|
||
|
}
|
||
|
i4++;
|
||
|
}
|
||
|
continue;
|
||
|
} else {
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
private void dispatchAndUpdateViewHolders(UpdateOp updateOp) {
|
||
|
int i;
|
||
|
int i2 = updateOp.cmd;
|
||
|
if (i2 == 1 || i2 == 8) {
|
||
|
throw new IllegalArgumentException("should not dispatch add or move for pre layout");
|
||
|
}
|
||
|
int updatePositionWithPostponed = updatePositionWithPostponed(updateOp.positionStart, i2);
|
||
|
int i3 = updateOp.positionStart;
|
||
|
int i4 = updateOp.cmd;
|
||
|
if (i4 == 2) {
|
||
|
i = 0;
|
||
|
} else if (i4 == 4) {
|
||
|
i = 1;
|
||
|
} else {
|
||
|
throw new IllegalArgumentException("op should be remove or update." + updateOp);
|
||
|
}
|
||
|
int i5 = 1;
|
||
|
for (int i6 = 1; i6 < updateOp.itemCount; i6++) {
|
||
|
int updatePositionWithPostponed2 = updatePositionWithPostponed((i * i6) + updateOp.positionStart, updateOp.cmd);
|
||
|
int i7 = updateOp.cmd;
|
||
|
if (i7 == 2 ? updatePositionWithPostponed2 == updatePositionWithPostponed : i7 == 4 && updatePositionWithPostponed2 == updatePositionWithPostponed + 1) {
|
||
|
i5++;
|
||
|
} else {
|
||
|
UpdateOp obtainUpdateOp = obtainUpdateOp(i7, updatePositionWithPostponed, i5, updateOp.payload);
|
||
|
dispatchFirstPassAndUpdateViewHolders(obtainUpdateOp, i3);
|
||
|
recycleUpdateOp(obtainUpdateOp);
|
||
|
if (updateOp.cmd == 4) {
|
||
|
i3 += i5;
|
||
|
}
|
||
|
updatePositionWithPostponed = updatePositionWithPostponed2;
|
||
|
i5 = 1;
|
||
|
}
|
||
|
}
|
||
|
Object obj = updateOp.payload;
|
||
|
recycleUpdateOp(updateOp);
|
||
|
if (i5 > 0) {
|
||
|
UpdateOp obtainUpdateOp2 = obtainUpdateOp(updateOp.cmd, updatePositionWithPostponed, i5, obj);
|
||
|
dispatchFirstPassAndUpdateViewHolders(obtainUpdateOp2, i3);
|
||
|
recycleUpdateOp(obtainUpdateOp2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void postponeAndUpdateViewHolders(UpdateOp updateOp) {
|
||
|
this.mPostponedList.add(updateOp);
|
||
|
int i = updateOp.cmd;
|
||
|
if (i == 1) {
|
||
|
this.mCallback.offsetPositionsForAdd(updateOp.positionStart, updateOp.itemCount);
|
||
|
} else if (i == 2) {
|
||
|
this.mCallback.offsetPositionsForRemovingLaidOutOrNewView(updateOp.positionStart, updateOp.itemCount);
|
||
|
} else if (i == 4) {
|
||
|
this.mCallback.markViewHoldersUpdated(updateOp.positionStart, updateOp.itemCount, updateOp.payload);
|
||
|
} else if (i == 8) {
|
||
|
this.mCallback.offsetPositionsForMove(updateOp.positionStart, updateOp.itemCount);
|
||
|
} else {
|
||
|
throw new IllegalArgumentException("Unknown update op type for " + updateOp);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private int updatePositionWithPostponed(int i, int i2) {
|
||
|
int i3;
|
||
|
int i4;
|
||
|
for (int size = this.mPostponedList.size() - 1; size >= 0; size--) {
|
||
|
UpdateOp updateOp = this.mPostponedList.get(size);
|
||
|
int i5 = updateOp.cmd;
|
||
|
if (i5 == 8) {
|
||
|
int i6 = updateOp.positionStart;
|
||
|
int i7 = updateOp.itemCount;
|
||
|
if (i6 < i7) {
|
||
|
i4 = i6;
|
||
|
i3 = i7;
|
||
|
} else {
|
||
|
i3 = i6;
|
||
|
i4 = i7;
|
||
|
}
|
||
|
if (i < i4 || i > i3) {
|
||
|
if (i < i6) {
|
||
|
if (i2 == 1) {
|
||
|
updateOp.positionStart = i6 + 1;
|
||
|
updateOp.itemCount = i7 + 1;
|
||
|
} else if (i2 == 2) {
|
||
|
updateOp.positionStart = i6 - 1;
|
||
|
updateOp.itemCount = i7 - 1;
|
||
|
}
|
||
|
}
|
||
|
} else if (i4 == i6) {
|
||
|
if (i2 == 1) {
|
||
|
updateOp.itemCount = i7 + 1;
|
||
|
} else if (i2 == 2) {
|
||
|
updateOp.itemCount = i7 - 1;
|
||
|
}
|
||
|
i++;
|
||
|
} else {
|
||
|
if (i2 == 1) {
|
||
|
updateOp.positionStart = i6 + 1;
|
||
|
} else if (i2 == 2) {
|
||
|
updateOp.positionStart = i6 - 1;
|
||
|
}
|
||
|
i--;
|
||
|
}
|
||
|
} else {
|
||
|
int i8 = updateOp.positionStart;
|
||
|
if (i8 <= i) {
|
||
|
if (i5 == 1) {
|
||
|
i -= updateOp.itemCount;
|
||
|
} else if (i5 == 2) {
|
||
|
i += updateOp.itemCount;
|
||
|
}
|
||
|
} else if (i2 == 1) {
|
||
|
updateOp.positionStart = i8 + 1;
|
||
|
} else if (i2 == 2) {
|
||
|
updateOp.positionStart = i8 - 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
for (int size2 = this.mPostponedList.size() - 1; size2 >= 0; size2--) {
|
||
|
UpdateOp updateOp2 = this.mPostponedList.get(size2);
|
||
|
if (updateOp2.cmd == 8) {
|
||
|
int i9 = updateOp2.itemCount;
|
||
|
if (i9 == updateOp2.positionStart || i9 < 0) {
|
||
|
this.mPostponedList.remove(size2);
|
||
|
recycleUpdateOp(updateOp2);
|
||
|
}
|
||
|
} else if (updateOp2.itemCount <= 0) {
|
||
|
this.mPostponedList.remove(size2);
|
||
|
recycleUpdateOp(updateOp2);
|
||
|
}
|
||
|
}
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
public AdapterHelper addUpdateOp(UpdateOp... updateOpArr) {
|
||
|
Collections.addAll(this.mPendingUpdates, updateOpArr);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
public int applyPendingUpdatesToPosition(int i) {
|
||
|
int size = this.mPendingUpdates.size();
|
||
|
for (int i2 = 0; i2 < size; i2++) {
|
||
|
UpdateOp updateOp = this.mPendingUpdates.get(i2);
|
||
|
int i3 = updateOp.cmd;
|
||
|
if (i3 != 1) {
|
||
|
if (i3 == 2) {
|
||
|
int i4 = updateOp.positionStart;
|
||
|
if (i4 <= i) {
|
||
|
int i5 = updateOp.itemCount;
|
||
|
if (i4 + i5 > i) {
|
||
|
return -1;
|
||
|
}
|
||
|
i -= i5;
|
||
|
} else {
|
||
|
continue;
|
||
|
}
|
||
|
} else if (i3 == 8) {
|
||
|
int i6 = updateOp.positionStart;
|
||
|
if (i6 == i) {
|
||
|
i = updateOp.itemCount;
|
||
|
} else {
|
||
|
if (i6 < i) {
|
||
|
i--;
|
||
|
}
|
||
|
if (updateOp.itemCount <= i) {
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} else if (updateOp.positionStart <= i) {
|
||
|
i += updateOp.itemCount;
|
||
|
}
|
||
|
}
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
public void consumePostponedUpdates() {
|
||
|
int size = this.mPostponedList.size();
|
||
|
for (int i = 0; i < size; i++) {
|
||
|
this.mCallback.onDispatchSecondPass(this.mPostponedList.get(i));
|
||
|
}
|
||
|
recycleUpdateOpsAndClearList(this.mPostponedList);
|
||
|
this.mExistingUpdateTypes = 0;
|
||
|
}
|
||
|
|
||
|
public void consumeUpdatesInOnePass() {
|
||
|
consumePostponedUpdates();
|
||
|
int size = this.mPendingUpdates.size();
|
||
|
for (int i = 0; i < size; i++) {
|
||
|
UpdateOp updateOp = this.mPendingUpdates.get(i);
|
||
|
int i2 = updateOp.cmd;
|
||
|
if (i2 == 1) {
|
||
|
this.mCallback.onDispatchSecondPass(updateOp);
|
||
|
this.mCallback.offsetPositionsForAdd(updateOp.positionStart, updateOp.itemCount);
|
||
|
} else if (i2 == 2) {
|
||
|
this.mCallback.onDispatchSecondPass(updateOp);
|
||
|
this.mCallback.offsetPositionsForRemovingInvisible(updateOp.positionStart, updateOp.itemCount);
|
||
|
} else if (i2 == 4) {
|
||
|
this.mCallback.onDispatchSecondPass(updateOp);
|
||
|
this.mCallback.markViewHoldersUpdated(updateOp.positionStart, updateOp.itemCount, updateOp.payload);
|
||
|
} else if (i2 == 8) {
|
||
|
this.mCallback.onDispatchSecondPass(updateOp);
|
||
|
this.mCallback.offsetPositionsForMove(updateOp.positionStart, updateOp.itemCount);
|
||
|
}
|
||
|
Runnable runnable = this.mOnItemProcessedCallback;
|
||
|
if (runnable != null) {
|
||
|
runnable.run();
|
||
|
}
|
||
|
}
|
||
|
recycleUpdateOpsAndClearList(this.mPendingUpdates);
|
||
|
this.mExistingUpdateTypes = 0;
|
||
|
}
|
||
|
|
||
|
public void dispatchFirstPassAndUpdateViewHolders(UpdateOp updateOp, int i) {
|
||
|
this.mCallback.onDispatchFirstPass(updateOp);
|
||
|
int i2 = updateOp.cmd;
|
||
|
if (i2 == 2) {
|
||
|
this.mCallback.offsetPositionsForRemovingInvisible(i, updateOp.itemCount);
|
||
|
} else if (i2 == 4) {
|
||
|
this.mCallback.markViewHoldersUpdated(i, updateOp.itemCount, updateOp.payload);
|
||
|
} else {
|
||
|
throw new IllegalArgumentException("only remove and update ops can be dispatched in first pass");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public int findPositionOffset(int i) {
|
||
|
return findPositionOffset(i, 0);
|
||
|
}
|
||
|
|
||
|
public int findPositionOffset(int i, int i2) {
|
||
|
int size = this.mPostponedList.size();
|
||
|
while (i2 < size) {
|
||
|
UpdateOp updateOp = this.mPostponedList.get(i2);
|
||
|
int i3 = updateOp.cmd;
|
||
|
if (i3 == 8) {
|
||
|
int i4 = updateOp.positionStart;
|
||
|
if (i4 == i) {
|
||
|
i = updateOp.itemCount;
|
||
|
} else {
|
||
|
if (i4 < i) {
|
||
|
i--;
|
||
|
}
|
||
|
if (updateOp.itemCount <= i) {
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
int i5 = updateOp.positionStart;
|
||
|
if (i5 > i) {
|
||
|
continue;
|
||
|
} else if (i3 == 2) {
|
||
|
int i6 = updateOp.itemCount;
|
||
|
if (i < i5 + i6) {
|
||
|
return -1;
|
||
|
}
|
||
|
i -= i6;
|
||
|
} else if (i3 == 1) {
|
||
|
i += updateOp.itemCount;
|
||
|
}
|
||
|
}
|
||
|
i2++;
|
||
|
}
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
public boolean hasAnyUpdateTypes(int i) {
|
||
|
return (i & this.mExistingUpdateTypes) != 0;
|
||
|
}
|
||
|
|
||
|
public boolean hasPendingUpdates() {
|
||
|
return this.mPendingUpdates.size() > 0;
|
||
|
}
|
||
|
|
||
|
public boolean hasUpdates() {
|
||
|
return !this.mPostponedList.isEmpty() && !this.mPendingUpdates.isEmpty();
|
||
|
}
|
||
|
|
||
|
@Override // androidx.recyclerview.widget.OpReorderer.Callback
|
||
|
public UpdateOp obtainUpdateOp(int i, int i2, int i3, Object obj) {
|
||
|
UpdateOp acquire = this.mUpdateOpPool.acquire();
|
||
|
if (acquire == null) {
|
||
|
return new UpdateOp(i, i2, i3, obj);
|
||
|
}
|
||
|
acquire.cmd = i;
|
||
|
acquire.positionStart = i2;
|
||
|
acquire.itemCount = i3;
|
||
|
acquire.payload = obj;
|
||
|
return acquire;
|
||
|
}
|
||
|
|
||
|
public boolean onItemRangeChanged(int i, int i2, Object obj) {
|
||
|
if (i2 < 1) {
|
||
|
return false;
|
||
|
}
|
||
|
this.mPendingUpdates.add(obtainUpdateOp(4, i, i2, obj));
|
||
|
this.mExistingUpdateTypes |= 4;
|
||
|
return this.mPendingUpdates.size() == 1;
|
||
|
}
|
||
|
|
||
|
public boolean onItemRangeInserted(int i, int i2) {
|
||
|
if (i2 < 1) {
|
||
|
return false;
|
||
|
}
|
||
|
this.mPendingUpdates.add(obtainUpdateOp(1, i, i2, null));
|
||
|
this.mExistingUpdateTypes |= 1;
|
||
|
return this.mPendingUpdates.size() == 1;
|
||
|
}
|
||
|
|
||
|
public boolean onItemRangeMoved(int i, int i2, int i3) {
|
||
|
if (i == i2) {
|
||
|
return false;
|
||
|
}
|
||
|
if (i3 == 1) {
|
||
|
this.mPendingUpdates.add(obtainUpdateOp(8, i, i2, null));
|
||
|
this.mExistingUpdateTypes |= 8;
|
||
|
return this.mPendingUpdates.size() == 1;
|
||
|
}
|
||
|
throw new IllegalArgumentException("Moving more than 1 item is not supported yet");
|
||
|
}
|
||
|
|
||
|
public boolean onItemRangeRemoved(int i, int i2) {
|
||
|
if (i2 < 1) {
|
||
|
return false;
|
||
|
}
|
||
|
this.mPendingUpdates.add(obtainUpdateOp(2, i, i2, null));
|
||
|
this.mExistingUpdateTypes |= 2;
|
||
|
return this.mPendingUpdates.size() == 1;
|
||
|
}
|
||
|
|
||
|
public void preProcess() {
|
||
|
this.mOpReorderer.reorderOps(this.mPendingUpdates);
|
||
|
int size = this.mPendingUpdates.size();
|
||
|
for (int i = 0; i < size; i++) {
|
||
|
UpdateOp updateOp = this.mPendingUpdates.get(i);
|
||
|
int i2 = updateOp.cmd;
|
||
|
if (i2 == 1) {
|
||
|
applyAdd(updateOp);
|
||
|
} else if (i2 == 2) {
|
||
|
applyRemove(updateOp);
|
||
|
} else if (i2 == 4) {
|
||
|
applyUpdate(updateOp);
|
||
|
} else if (i2 == 8) {
|
||
|
applyMove(updateOp);
|
||
|
}
|
||
|
Runnable runnable = this.mOnItemProcessedCallback;
|
||
|
if (runnable != null) {
|
||
|
runnable.run();
|
||
|
}
|
||
|
}
|
||
|
this.mPendingUpdates.clear();
|
||
|
}
|
||
|
|
||
|
@Override // androidx.recyclerview.widget.OpReorderer.Callback
|
||
|
public void recycleUpdateOp(UpdateOp updateOp) {
|
||
|
if (!this.mDisableRecycler) {
|
||
|
updateOp.payload = null;
|
||
|
this.mUpdateOpPool.release(updateOp);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void recycleUpdateOpsAndClearList(List<UpdateOp> list) {
|
||
|
int size = list.size();
|
||
|
for (int i = 0; i < size; i++) {
|
||
|
recycleUpdateOp(list.get(i));
|
||
|
}
|
||
|
list.clear();
|
||
|
}
|
||
|
|
||
|
public void reset() {
|
||
|
recycleUpdateOpsAndClearList(this.mPendingUpdates);
|
||
|
recycleUpdateOpsAndClearList(this.mPostponedList);
|
||
|
this.mExistingUpdateTypes = 0;
|
||
|
}
|
||
|
}
|