private void DispatchRemovals <T>(List <PostponedUpdate> postponedUpdates, MvxObservableCollection <T> updateCallback, IList <T> source, int start, int count, int globalIndex) { if (!mDetectMoves) { //updateCallback.onRemoved(start, count); updateCallback.RemoveRange(start, count); return; } for (int i = count - 1; i >= 0; i--) { int status = mOldItemStatuses[globalIndex + i] & FLAG_MASK; switch (status) { case 0: // real removal //updateCallback.onRemoved(start + i, 1); updateCallback.RemoveAt(start + i); foreach (PostponedUpdate upd in postponedUpdates) { upd.currentPos -= 1; } break; case FLAG_MOVED_CHANGED: case FLAG_MOVED_NOT_CHANGED: int pos = mOldItemStatuses[globalIndex + i] >> FLAG_OFFSET; PostponedUpdate update = RemovePostponedUpdate(postponedUpdates, pos, false); // the item was moved to that position. we do -1 because this is a move not // add and removing current item offsets the target move by 1 //noinspection ConstantConditions //updateCallback.onMoved(start + i, update.currentPos - 1); updateCallback.RemoveAt(start + i); updateCallback.Insert(update.currentPos - 1, source[update.currentPos - 1]); //if (status == FLAG_MOVED_CHANGED) //{ // // also dispatch a change // updateCallback.onChanged(update.currentPos - 1, 1, // mCallback.getChangePayload(globalIndex + i, pos)); //} break; case FLAG_IGNORE: // ignoring this postponedUpdates.Add(new PostponedUpdate(globalIndex + i, start + i, true)); break; default: throw new Exception( "unknown flag for pos " + (globalIndex + i) + " " + status); } } }
private void DispatchAdditions <T>(List <PostponedUpdate> postponedUpdates, MvxObservableCollection <T> updateCallback, IList <T> source, int start, int count, int globalIndex) { if (!mDetectMoves) { //updateCallback.onInserted(start, count); updateCallback.InsertRange(start, source.Skip(start).Take(count)); return; } for (int i = count - 1; i >= 0; i--) { int status = mNewItemStatuses[globalIndex + i] & FLAG_MASK; switch (status) { case 0: // real addition //updateCallback.onInserted(start, 1); updateCallback.Insert(start, source[start]); foreach (PostponedUpdate upd in postponedUpdates) { upd.currentPos += 1; } break; case FLAG_MOVED_CHANGED: case FLAG_MOVED_NOT_CHANGED: int pos = mNewItemStatuses[globalIndex + i] >> FLAG_OFFSET; PostponedUpdate update = RemovePostponedUpdate(postponedUpdates, pos, true); // the item was moved from that position //noinspection ConstantConditions //updateCallback.onMoved(update.currentPos, start); updateCallback.RemoveAt(update.currentPos); updateCallback.Insert(start, source[start]); //if (status == FLAG_MOVED_CHANGED) //{ // // also dispatch a change // updateCallback.onChanged(start, 1, // mCallback.getChangePayload(pos, globalIndex + i)); //} break; case FLAG_IGNORE: // ignoring this postponedUpdates.Add(new PostponedUpdate(globalIndex + i, start, false)); break; default: throw new Exception( "unknown flag for pos " + (globalIndex + i) + " " + status); } } }
private static PostponedUpdate RemovePostponedUpdate(List <PostponedUpdate> updates, int pos, bool removal) { for (int i = updates.Count - 1; i >= 0; i--) { PostponedUpdate update = updates[i]; if (update.posInOwnerList == pos && update.removal == removal) { updates.RemoveAt(i); for (int j = i; j < updates.Count; j++) { // offset other ops since they swapped positions updates[j].currentPos += removal ? 1 : -1; } return(update); } } return(null); }