DefaultItemAnimator.java revision abea494886a17e7a51080ab5e9c2ca041c533353
1d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase/* 2d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Copyright (C) 2014 The Android Open Source Project 3d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 4d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Licensed under the Apache License, Version 2.0 (the "License"); 5d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * you may not use this file except in compliance with the License. 6d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * You may obtain a copy of the License at 7d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 8d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * http://www.apache.org/licenses/LICENSE-2.0 9d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 10d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Unless required by applicable law or agreed to in writing, software 11d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * distributed under the License is distributed on an "AS IS" BASIS, 12d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * See the License for the specific language governing permissions and 14d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * limitations under the License. 15d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 16d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haasepackage android.support.v7.widget; 17d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 18abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyarimport android.support.annotation.NonNull; 19d03a495b04ee74c1cb493cee0d5998b895b1c79bVladislav Kaznacheevimport android.support.v4.animation.AnimatorCompatHelper; 20d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haaseimport android.support.v4.view.ViewCompat; 21a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyarimport android.support.v4.view.ViewPropertyAnimatorCompat; 22d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haaseimport android.support.v4.view.ViewPropertyAnimatorListener; 23d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haaseimport android.support.v7.widget.RecyclerView.ViewHolder; 24d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haaseimport android.view.View; 25d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 26d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haaseimport java.util.ArrayList; 27a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyarimport java.util.List; 28d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 29d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase/** 30d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * This implementation of {@link RecyclerView.ItemAnimator} provides basic 31d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * animations on remove, add, and move events that happen to the items in 32d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * a RecyclerView. RecyclerView uses a DefaultItemAnimator by default. 33d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 34d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * @see RecyclerView#setItemAnimator(RecyclerView.ItemAnimator) 35d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 36121ba9616e5bed44d2490f1744f7b6a9d3e79866Yigit Boyarpublic class DefaultItemAnimator extends SimpleItemAnimator { 37a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar private static final boolean DEBUG = false; 38d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 39e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar private ArrayList<ViewHolder> mPendingRemovals = new ArrayList<>(); 40e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar private ArrayList<ViewHolder> mPendingAdditions = new ArrayList<>(); 41e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar private ArrayList<MoveInfo> mPendingMoves = new ArrayList<>(); 42e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar private ArrayList<ChangeInfo> mPendingChanges = new ArrayList<>(); 43d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 44e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar private ArrayList<ArrayList<ViewHolder>> mAdditionsList = new ArrayList<>(); 45e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar private ArrayList<ArrayList<MoveInfo>> mMovesList = new ArrayList<>(); 46e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar private ArrayList<ArrayList<ChangeInfo>> mChangesList = new ArrayList<>(); 47d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 48e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar private ArrayList<ViewHolder> mAddAnimations = new ArrayList<>(); 49e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar private ArrayList<ViewHolder> mMoveAnimations = new ArrayList<>(); 50e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar private ArrayList<ViewHolder> mRemoveAnimations = new ArrayList<>(); 51e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar private ArrayList<ViewHolder> mChangeAnimations = new ArrayList<>(); 52d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 53d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase private static class MoveInfo { 54d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public ViewHolder holder; 55d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public int fromX, fromY, toX, toY; 56d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 57d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase private MoveInfo(ViewHolder holder, int fromX, int fromY, int toX, int toY) { 58d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase this.holder = holder; 59d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase this.fromX = fromX; 60d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase this.fromY = fromY; 61d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase this.toX = toX; 62d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase this.toY = toY; 63d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 64d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 65d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 66235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase private static class ChangeInfo { 67235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase public ViewHolder oldHolder, newHolder; 68a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar public int fromX, fromY, toX, toY; 69235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase private ChangeInfo(ViewHolder oldHolder, ViewHolder newHolder) { 70235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase this.oldHolder = oldHolder; 71235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase this.newHolder = newHolder; 72235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 73a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar 74a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar private ChangeInfo(ViewHolder oldHolder, ViewHolder newHolder, 75a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar int fromX, int fromY, int toX, int toY) { 76a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar this(oldHolder, newHolder); 77a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar this.fromX = fromX; 78a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar this.fromY = fromY; 79a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar this.toX = toX; 80a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar this.toY = toY; 81a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar } 82a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar 83a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar @Override 84a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar public String toString() { 85a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar return "ChangeInfo{" + 86a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar "oldHolder=" + oldHolder + 87a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ", newHolder=" + newHolder + 88a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ", fromX=" + fromX + 89a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ", fromY=" + fromY + 90a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ", toX=" + toX + 91a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ", toY=" + toY + 92a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar '}'; 93a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar } 94235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 95235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase 96d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 97d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public void runPendingAnimations() { 98d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase boolean removalsPending = !mPendingRemovals.isEmpty(); 99d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase boolean movesPending = !mPendingMoves.isEmpty(); 100235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase boolean changesPending = !mPendingChanges.isEmpty(); 101d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase boolean additionsPending = !mPendingAdditions.isEmpty(); 102a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar if (!removalsPending && !movesPending && !additionsPending && !changesPending) { 103d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase // nothing to animate 104d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return; 105d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 106d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase // First, remove stuff 107d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase for (ViewHolder holder : mPendingRemovals) { 108d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase animateRemoveImpl(holder); 109d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 110d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase mPendingRemovals.clear(); 111d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase // Next, move stuff 112d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if (movesPending) { 113e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar final ArrayList<MoveInfo> moves = new ArrayList<>(); 1140e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase moves.addAll(mPendingMoves); 1150e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase mMovesList.add(moves); 116d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase mPendingMoves.clear(); 117d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase Runnable mover = new Runnable() { 118d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 119d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public void run() { 1200e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase for (MoveInfo moveInfo : moves) { 121d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase animateMoveImpl(moveInfo.holder, moveInfo.fromX, moveInfo.fromY, 122d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase moveInfo.toX, moveInfo.toY); 123d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 1240e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase moves.clear(); 1250e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase mMovesList.remove(moves); 126d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 127d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase }; 128d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if (removalsPending) { 1290e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase View view = moves.get(0).holder.itemView; 130d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase ViewCompat.postOnAnimationDelayed(view, mover, getRemoveDuration()); 131d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } else { 132d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase mover.run(); 133d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 134d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 135235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase // Next, change stuff, to run in parallel with move animations 136235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase if (changesPending) { 137e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar final ArrayList<ChangeInfo> changes = new ArrayList<>(); 1380e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase changes.addAll(mPendingChanges); 1390e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase mChangesList.add(changes); 140235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase mPendingChanges.clear(); 141235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase Runnable changer = new Runnable() { 142235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase @Override 143235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase public void run() { 1440e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase for (ChangeInfo change : changes) { 145235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase animateChangeImpl(change); 146235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 1470e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase changes.clear(); 1480e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase mChangesList.remove(changes); 149235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 150235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase }; 151235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase if (removalsPending) { 1520e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase ViewHolder holder = changes.get(0).oldHolder; 153235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase ViewCompat.postOnAnimationDelayed(holder.itemView, changer, getRemoveDuration()); 154235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } else { 155235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase changer.run(); 156235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 157235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 158d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase // Next, add stuff 159d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if (additionsPending) { 160e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar final ArrayList<ViewHolder> additions = new ArrayList<>(); 1610e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase additions.addAll(mPendingAdditions); 1620e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase mAdditionsList.add(additions); 163d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase mPendingAdditions.clear(); 164d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase Runnable adder = new Runnable() { 165d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public void run() { 1660e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase for (ViewHolder holder : additions) { 167d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase animateAddImpl(holder); 168d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 1690e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase additions.clear(); 1700e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase mAdditionsList.remove(additions); 171d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 172d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase }; 173549bbdfca3cffe64fd3ef69723a54037df326689Chet Haase if (removalsPending || movesPending || changesPending) { 174235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase long removeDuration = removalsPending ? getRemoveDuration() : 0; 175235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase long moveDuration = movesPending ? getMoveDuration() : 0; 176235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase long changeDuration = changesPending ? getChangeDuration() : 0; 177235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase long totalDelay = removeDuration + Math.max(moveDuration, changeDuration); 1780e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase View view = additions.get(0).itemView; 179235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase ViewCompat.postOnAnimationDelayed(view, adder, totalDelay); 180d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } else { 181d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase adder.run(); 182d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 183d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 184d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 185d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 186d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 187d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public boolean animateRemove(final ViewHolder holder) { 188d03a495b04ee74c1cb493cee0d5998b895b1c79bVladislav Kaznacheev resetAnimation(holder); 189d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase mPendingRemovals.add(holder); 190d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return true; 191d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 192d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 193d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase private void animateRemoveImpl(final ViewHolder holder) { 194d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase final View view = holder.itemView; 19507715e8dcfa3e9fcd6c3e7727f61ca41b50e5763Dake Gu final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view); 1964d21e073e1aa2eb08777c288d08a92c419faa1e9Yigit Boyar mRemoveAnimations.add(holder); 19707715e8dcfa3e9fcd6c3e7727f61ca41b50e5763Dake Gu animation.setDuration(getRemoveDuration()) 19807715e8dcfa3e9fcd6c3e7727f61ca41b50e5763Dake Gu .alpha(0).setListener(new VpaListenerAdapter() { 199d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 200e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase public void onAnimationStart(View view) { 201e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase dispatchRemoveStarting(holder); 202e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase } 2034d21e073e1aa2eb08777c288d08a92c419faa1e9Yigit Boyar 204e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase @Override 205d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public void onAnimationEnd(View view) { 20607715e8dcfa3e9fcd6c3e7727f61ca41b50e5763Dake Gu animation.setListener(null); 207d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase ViewCompat.setAlpha(view, 1); 208d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase dispatchRemoveFinished(holder); 209d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase mRemoveAnimations.remove(holder); 210d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase dispatchFinishedWhenDone(); 211d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 212d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase }).start(); 213d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 214d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 215d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 216d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public boolean animateAdd(final ViewHolder holder) { 217d03a495b04ee74c1cb493cee0d5998b895b1c79bVladislav Kaznacheev resetAnimation(holder); 218d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase ViewCompat.setAlpha(holder.itemView, 0); 219d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase mPendingAdditions.add(holder); 220d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return true; 221d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 222d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 223d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase private void animateAddImpl(final ViewHolder holder) { 224d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase final View view = holder.itemView; 22507715e8dcfa3e9fcd6c3e7727f61ca41b50e5763Dake Gu final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view); 2264d21e073e1aa2eb08777c288d08a92c419faa1e9Yigit Boyar mAddAnimations.add(holder); 22707715e8dcfa3e9fcd6c3e7727f61ca41b50e5763Dake Gu animation.alpha(1).setDuration(getAddDuration()). 228d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase setListener(new VpaListenerAdapter() { 229d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 230e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase public void onAnimationStart(View view) { 231e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase dispatchAddStarting(holder); 232e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase } 233e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase @Override 234d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public void onAnimationCancel(View view) { 235d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase ViewCompat.setAlpha(view, 1); 236d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 237c35968d173f900d8024bdf38174e2225c9a7f311Chet Haase 238d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 239d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public void onAnimationEnd(View view) { 24007715e8dcfa3e9fcd6c3e7727f61ca41b50e5763Dake Gu animation.setListener(null); 241d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase dispatchAddFinished(holder); 242d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase mAddAnimations.remove(holder); 243d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase dispatchFinishedWhenDone(); 244d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 245d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase }).start(); 246d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 247d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 248d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 249d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public boolean animateMove(final ViewHolder holder, int fromX, int fromY, 250d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase int toX, int toY) { 251d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase final View view = holder.itemView; 252504c54ea52c1b2aae6f8f4ae128f1dcaac7e3f6aYigit Boyar fromX += ViewCompat.getTranslationX(holder.itemView); 253504c54ea52c1b2aae6f8f4ae128f1dcaac7e3f6aYigit Boyar fromY += ViewCompat.getTranslationY(holder.itemView); 254d03a495b04ee74c1cb493cee0d5998b895b1c79bVladislav Kaznacheev resetAnimation(holder); 255d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase int deltaX = toX - fromX; 256d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase int deltaY = toY - fromY; 257d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if (deltaX == 0 && deltaY == 0) { 258d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase dispatchMoveFinished(holder); 259d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return false; 260d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 261d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if (deltaX != 0) { 262d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase ViewCompat.setTranslationX(view, -deltaX); 263d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 264d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if (deltaY != 0) { 265d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase ViewCompat.setTranslationY(view, -deltaY); 266d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 267d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase mPendingMoves.add(new MoveInfo(holder, fromX, fromY, toX, toY)); 268d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return true; 269d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 270d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 271d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase private void animateMoveImpl(final ViewHolder holder, int fromX, int fromY, int toX, int toY) { 272d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase final View view = holder.itemView; 273d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase final int deltaX = toX - fromX; 274d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase final int deltaY = toY - fromY; 275d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if (deltaX != 0) { 276d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase ViewCompat.animate(view).translationX(0); 277d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 278d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if (deltaY != 0) { 279d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase ViewCompat.animate(view).translationY(0); 280d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 281d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase // TODO: make EndActions end listeners instead, since end actions aren't called when 282d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase // vpas are canceled (and can't end them. why?) 283d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase // need listener functionality in VPACompat for this. Ick. 28407715e8dcfa3e9fcd6c3e7727f61ca41b50e5763Dake Gu final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view); 2854d21e073e1aa2eb08777c288d08a92c419faa1e9Yigit Boyar mMoveAnimations.add(holder); 28607715e8dcfa3e9fcd6c3e7727f61ca41b50e5763Dake Gu animation.setDuration(getMoveDuration()).setListener(new VpaListenerAdapter() { 287d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 288e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase public void onAnimationStart(View view) { 289e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase dispatchMoveStarting(holder); 290e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase } 291e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase @Override 292d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public void onAnimationCancel(View view) { 293d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if (deltaX != 0) { 294d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase ViewCompat.setTranslationX(view, 0); 295d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 296d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if (deltaY != 0) { 297d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase ViewCompat.setTranslationY(view, 0); 298d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 299d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 300d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 301d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public void onAnimationEnd(View view) { 30207715e8dcfa3e9fcd6c3e7727f61ca41b50e5763Dake Gu animation.setListener(null); 303d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase dispatchMoveFinished(holder); 304d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase mMoveAnimations.remove(holder); 305d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase dispatchFinishedWhenDone(); 306d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 307d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase }).start(); 308d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 309d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 310d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 311a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar public boolean animateChange(ViewHolder oldHolder, ViewHolder newHolder, 312a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar int fromX, int fromY, int toX, int toY) { 313121ba9616e5bed44d2490f1744f7b6a9d3e79866Yigit Boyar if (oldHolder == newHolder) { 314121ba9616e5bed44d2490f1744f7b6a9d3e79866Yigit Boyar // Don't know how to run change animations when the same view holder is re-used. 315121ba9616e5bed44d2490f1744f7b6a9d3e79866Yigit Boyar // run a move animation to handle position changes. 316121ba9616e5bed44d2490f1744f7b6a9d3e79866Yigit Boyar return animateMove(oldHolder, fromX, fromY, toX, toY); 317121ba9616e5bed44d2490f1744f7b6a9d3e79866Yigit Boyar } 318a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar final float prevTranslationX = ViewCompat.getTranslationX(oldHolder.itemView); 319a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar final float prevTranslationY = ViewCompat.getTranslationY(oldHolder.itemView); 320a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar final float prevAlpha = ViewCompat.getAlpha(oldHolder.itemView); 321d03a495b04ee74c1cb493cee0d5998b895b1c79bVladislav Kaznacheev resetAnimation(oldHolder); 322a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar int deltaX = (int) (toX - fromX - prevTranslationX); 323a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar int deltaY = (int) (toY - fromY - prevTranslationY); 324a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar // recover prev translation state after ending animation 325a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ViewCompat.setTranslationX(oldHolder.itemView, prevTranslationX); 326a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ViewCompat.setTranslationY(oldHolder.itemView, prevTranslationY); 327a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ViewCompat.setAlpha(oldHolder.itemView, prevAlpha); 328e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar if (newHolder != null) { 329a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar // carry over translation values 330d03a495b04ee74c1cb493cee0d5998b895b1c79bVladislav Kaznacheev resetAnimation(newHolder); 331a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ViewCompat.setTranslationX(newHolder.itemView, -deltaX); 332a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ViewCompat.setTranslationY(newHolder.itemView, -deltaY); 333235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase ViewCompat.setAlpha(newHolder.itemView, 0); 334235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 335a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar mPendingChanges.add(new ChangeInfo(oldHolder, newHolder, fromX, fromY, toX, toY)); 336235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase return true; 337235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 338235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase 339235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase private void animateChangeImpl(final ChangeInfo changeInfo) { 340235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase final ViewHolder holder = changeInfo.oldHolder; 34190ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar final View view = holder == null ? null : holder.itemView; 342235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase final ViewHolder newHolder = changeInfo.newHolder; 343235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase final View newView = newHolder != null ? newHolder.itemView : null; 34490ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar if (view != null) { 34590ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar final ViewPropertyAnimatorCompat oldViewAnim = ViewCompat.animate(view).setDuration( 34690ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar getChangeDuration()); 3474d21e073e1aa2eb08777c288d08a92c419faa1e9Yigit Boyar mChangeAnimations.add(changeInfo.oldHolder); 34890ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar oldViewAnim.translationX(changeInfo.toX - changeInfo.fromX); 34990ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar oldViewAnim.translationY(changeInfo.toY - changeInfo.fromY); 35090ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar oldViewAnim.alpha(0).setListener(new VpaListenerAdapter() { 35190ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar @Override 35290ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar public void onAnimationStart(View view) { 35390ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar dispatchChangeStarting(changeInfo.oldHolder, true); 35490ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar } 355a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar 35690ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar @Override 35790ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar public void onAnimationEnd(View view) { 35890ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar oldViewAnim.setListener(null); 35990ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar ViewCompat.setAlpha(view, 1); 36090ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar ViewCompat.setTranslationX(view, 0); 36190ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar ViewCompat.setTranslationY(view, 0); 36290ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar dispatchChangeFinished(changeInfo.oldHolder, true); 36390ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar mChangeAnimations.remove(changeInfo.oldHolder); 36490ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar dispatchFinishedWhenDone(); 36590ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar } 36690ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar }).start(); 36790ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar } 368235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase if (newView != null) { 36907715e8dcfa3e9fcd6c3e7727f61ca41b50e5763Dake Gu final ViewPropertyAnimatorCompat newViewAnimation = ViewCompat.animate(newView); 3704d21e073e1aa2eb08777c288d08a92c419faa1e9Yigit Boyar mChangeAnimations.add(changeInfo.newHolder); 371a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()). 372235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase alpha(1).setListener(new VpaListenerAdapter() { 373235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase @Override 374e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase public void onAnimationStart(View view) { 375e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase dispatchChangeStarting(changeInfo.newHolder, false); 376e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase } 377e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase @Override 378235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase public void onAnimationEnd(View view) { 37907715e8dcfa3e9fcd6c3e7727f61ca41b50e5763Dake Gu newViewAnimation.setListener(null); 380235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase ViewCompat.setAlpha(newView, 1); 381a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ViewCompat.setTranslationX(newView, 0); 382a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ViewCompat.setTranslationY(newView, 0); 383e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase dispatchChangeFinished(changeInfo.newHolder, false); 384a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar mChangeAnimations.remove(changeInfo.newHolder); 385a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar dispatchFinishedWhenDone(); 386235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 387235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase }).start(); 388235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 389a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar } 390a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar 391a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar private void endChangeAnimation(List<ChangeInfo> infoList, ViewHolder item) { 392a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar for (int i = infoList.size() - 1; i >= 0; i--) { 393a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ChangeInfo changeInfo = infoList.get(i); 394a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar if (endChangeAnimationIfNecessary(changeInfo, item)) { 395a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar if (changeInfo.oldHolder == null && changeInfo.newHolder == null) { 396a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar infoList.remove(changeInfo); 397a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar } 398a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar } 399a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar } 400a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar } 401a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar 402a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar private void endChangeAnimationIfNecessary(ChangeInfo changeInfo) { 403a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar if (changeInfo.oldHolder != null) { 404a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar endChangeAnimationIfNecessary(changeInfo, changeInfo.oldHolder); 405a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar } 406a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar if (changeInfo.newHolder != null) { 407a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar endChangeAnimationIfNecessary(changeInfo, changeInfo.newHolder); 408a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar } 409a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar } 410a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar private boolean endChangeAnimationIfNecessary(ChangeInfo changeInfo, ViewHolder item) { 411e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase boolean oldItem = false; 412a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar if (changeInfo.newHolder == item) { 413a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar changeInfo.newHolder = null; 414a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar } else if (changeInfo.oldHolder == item) { 415a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar changeInfo.oldHolder = null; 416e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase oldItem = true; 417a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar } else { 418a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar return false; 419a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar } 420a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ViewCompat.setAlpha(item.itemView, 1); 421a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ViewCompat.setTranslationX(item.itemView, 0); 422a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ViewCompat.setTranslationY(item.itemView, 0); 423e321eb5c831282c92a28a483692d8520b766a0a5Chet Haase dispatchChangeFinished(item, oldItem); 424a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar return true; 425235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 426235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase 427235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase @Override 428d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public void endAnimation(ViewHolder item) { 429d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase final View view = item.itemView; 430a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar // this will trigger end callback which should set properties to their target values. 431d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase ViewCompat.animate(view).cancel(); 432a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar // TODO if some other animations are chained to end, how do we cancel them as well? 433235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase for (int i = mPendingMoves.size() - 1; i >= 0; i--) { 434235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase MoveInfo moveInfo = mPendingMoves.get(i); 435235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase if (moveInfo.holder == item) { 436235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase ViewCompat.setTranslationY(view, 0); 437235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase ViewCompat.setTranslationX(view, 0); 438235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase dispatchMoveFinished(item); 4399457c0c167cca5aafe971fb2eb75f4a43c07ec05Yigit Boyar mPendingMoves.remove(i); 440235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 44193b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu } 442a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar endChangeAnimation(mPendingChanges, item); 443a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar if (mPendingRemovals.remove(item)) { 444a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ViewCompat.setAlpha(view, 1); 44593b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu dispatchRemoveFinished(item); 44693b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu } 447a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar if (mPendingAdditions.remove(item)) { 44893b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu ViewCompat.setAlpha(view, 1); 44993b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu dispatchAddFinished(item); 450235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 451a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar 4520e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase for (int i = mChangesList.size() - 1; i >= 0; i--) { 4530e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase ArrayList<ChangeInfo> changes = mChangesList.get(i); 4540e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase endChangeAnimation(changes, item); 4550e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase if (changes.isEmpty()) { 4569457c0c167cca5aafe971fb2eb75f4a43c07ec05Yigit Boyar mChangesList.remove(i); 457ec93520d243d3eb3c6cddeaea7908d1b869bf367Dake Gu } 458ec93520d243d3eb3c6cddeaea7908d1b869bf367Dake Gu } 4590e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase for (int i = mMovesList.size() - 1; i >= 0; i--) { 4600e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase ArrayList<MoveInfo> moves = mMovesList.get(i); 4610e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase for (int j = moves.size() - 1; j >= 0; j--) { 4620e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase MoveInfo moveInfo = moves.get(j); 4630e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase if (moveInfo.holder == item) { 4640e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase ViewCompat.setTranslationY(view, 0); 4650e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase ViewCompat.setTranslationX(view, 0); 4660e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase dispatchMoveFinished(item); 4670e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase moves.remove(j); 4680e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase if (moves.isEmpty()) { 4699457c0c167cca5aafe971fb2eb75f4a43c07ec05Yigit Boyar mMovesList.remove(i); 4700e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase } 4710e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase break; 4720e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase } 4730e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase } 4740e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase } 4750e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase for (int i = mAdditionsList.size() - 1; i >= 0; i--) { 4760e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase ArrayList<ViewHolder> additions = mAdditionsList.get(i); 4770e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase if (additions.remove(item)) { 4780e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase ViewCompat.setAlpha(view, 1); 4790e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase dispatchAddFinished(item); 4800e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase if (additions.isEmpty()) { 4819457c0c167cca5aafe971fb2eb75f4a43c07ec05Yigit Boyar mAdditionsList.remove(i); 4820e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase } 4830e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase } 484ec93520d243d3eb3c6cddeaea7908d1b869bf367Dake Gu } 485a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar 486a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar // animations should be ended by the cancel above. 487e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar //noinspection PointlessBooleanExpression,ConstantConditions 488a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar if (mRemoveAnimations.remove(item) && DEBUG) { 489a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar throw new IllegalStateException("after animation is cancelled, item should not be in " 490a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar + "mRemoveAnimations list"); 491d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 492a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar 493e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar //noinspection PointlessBooleanExpression,ConstantConditions 494a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar if (mAddAnimations.remove(item) && DEBUG) { 495a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar throw new IllegalStateException("after animation is cancelled, item should not be in " 496a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar + "mAddAnimations list"); 497d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 498a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar 499e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar //noinspection PointlessBooleanExpression,ConstantConditions 500a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar if (mChangeAnimations.remove(item) && DEBUG) { 501a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar throw new IllegalStateException("after animation is cancelled, item should not be in " 502a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar + "mChangeAnimations list"); 503a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar } 504a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar 505e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar //noinspection PointlessBooleanExpression,ConstantConditions 506a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar if (mMoveAnimations.remove(item) && DEBUG) { 507a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar throw new IllegalStateException("after animation is cancelled, item should not be in " 508a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar + "mMoveAnimations list"); 509235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 510d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase dispatchFinishedWhenDone(); 511d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 512d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 513d03a495b04ee74c1cb493cee0d5998b895b1c79bVladislav Kaznacheev private void resetAnimation(ViewHolder holder) { 514d03a495b04ee74c1cb493cee0d5998b895b1c79bVladislav Kaznacheev AnimatorCompatHelper.clearInterpolator(holder.itemView); 515d03a495b04ee74c1cb493cee0d5998b895b1c79bVladislav Kaznacheev endAnimation(holder); 516d03a495b04ee74c1cb493cee0d5998b895b1c79bVladislav Kaznacheev } 517d03a495b04ee74c1cb493cee0d5998b895b1c79bVladislav Kaznacheev 518d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 519d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public boolean isRunning() { 520e3d27c97eb0769997cd9d73baabffff70551efe0Yigit Boyar return (!mPendingAdditions.isEmpty() || 521047e1151b1ce6965f5578eac83ee1ac3cf524ba7Yigit Boyar !mPendingChanges.isEmpty() || 522047e1151b1ce6965f5578eac83ee1ac3cf524ba7Yigit Boyar !mPendingMoves.isEmpty() || 523047e1151b1ce6965f5578eac83ee1ac3cf524ba7Yigit Boyar !mPendingRemovals.isEmpty() || 524e3d27c97eb0769997cd9d73baabffff70551efe0Yigit Boyar !mMoveAnimations.isEmpty() || 525d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase !mRemoveAnimations.isEmpty() || 526d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase !mAddAnimations.isEmpty() || 527235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase !mChangeAnimations.isEmpty() || 5280e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase !mMovesList.isEmpty() || 5290e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase !mAdditionsList.isEmpty() || 5300e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase !mChangesList.isEmpty()); 531d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 532d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 533d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase /** 534d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Check the state of currently pending and running animations. If there are none 535d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * pending/running, call {@link #dispatchAnimationsFinished()} to notify any 536d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * listeners. 537d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 538d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase private void dispatchFinishedWhenDone() { 539d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if (!isRunning()) { 540d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase dispatchAnimationsFinished(); 541d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 542d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 543d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 544d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 545d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public void endAnimations() { 54693b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu int count = mPendingMoves.size(); 54793b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu for (int i = count - 1; i >= 0; i--) { 54893b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu MoveInfo item = mPendingMoves.get(i); 54993b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu View view = item.holder.itemView; 55093b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu ViewCompat.setTranslationY(view, 0); 55193b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu ViewCompat.setTranslationX(view, 0); 55293b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu dispatchMoveFinished(item.holder); 553ec93520d243d3eb3c6cddeaea7908d1b869bf367Dake Gu mPendingMoves.remove(i); 55493b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu } 55593b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu count = mPendingRemovals.size(); 55693b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu for (int i = count - 1; i >= 0; i--) { 55793b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu ViewHolder item = mPendingRemovals.get(i); 55893b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu dispatchRemoveFinished(item); 559ec93520d243d3eb3c6cddeaea7908d1b869bf367Dake Gu mPendingRemovals.remove(i); 56093b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu } 56193b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu count = mPendingAdditions.size(); 56293b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu for (int i = count - 1; i >= 0; i--) { 56393b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu ViewHolder item = mPendingAdditions.get(i); 56493b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu View view = item.itemView; 56593b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu ViewCompat.setAlpha(view, 1); 56693b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu dispatchAddFinished(item); 567ec93520d243d3eb3c6cddeaea7908d1b869bf367Dake Gu mPendingAdditions.remove(i); 56893b78dd7cbfafbe669e124b38a8e3ccb38ad3079Dake Gu } 569235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase count = mPendingChanges.size(); 570235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase for (int i = count - 1; i >= 0; i--) { 571a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar endChangeAnimationIfNecessary(mPendingChanges.get(i)); 572235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 573a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar mPendingChanges.clear(); 574d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase if (!isRunning()) { 575d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase return; 576d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 577235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase 5780e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase int listCount = mMovesList.size(); 5790e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase for (int i = listCount - 1; i >= 0; i--) { 5800e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase ArrayList<MoveInfo> moves = mMovesList.get(i); 5810e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase count = moves.size(); 5820e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase for (int j = count - 1; j >= 0; j--) { 5830e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase MoveInfo moveInfo = moves.get(j); 5840e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase ViewHolder item = moveInfo.holder; 5850e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase View view = item.itemView; 5860e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase ViewCompat.setTranslationY(view, 0); 5870e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase ViewCompat.setTranslationX(view, 0); 5880e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase dispatchMoveFinished(moveInfo.holder); 5890e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase moves.remove(j); 5900e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase if (moves.isEmpty()) { 5910e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase mMovesList.remove(moves); 5920e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase } 5930e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase } 594235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 5950e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase listCount = mAdditionsList.size(); 5960e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase for (int i = listCount - 1; i >= 0; i--) { 5970e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase ArrayList<ViewHolder> additions = mAdditionsList.get(i); 5980e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase count = additions.size(); 5990e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase for (int j = count - 1; j >= 0; j--) { 6000e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase ViewHolder item = additions.get(j); 6010e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase View view = item.itemView; 6020e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase ViewCompat.setAlpha(view, 1); 6030e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase dispatchAddFinished(item); 6040e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase additions.remove(j); 6050e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase if (additions.isEmpty()) { 6060e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase mAdditionsList.remove(additions); 6070e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase } 6080e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase } 609235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 6100e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase listCount = mChangesList.size(); 6110e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase for (int i = listCount - 1; i >= 0; i--) { 6120e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase ArrayList<ChangeInfo> changes = mChangesList.get(i); 6130e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase count = changes.size(); 6140e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase for (int j = count - 1; j >= 0; j--) { 6150e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase endChangeAnimationIfNecessary(changes.get(j)); 6160e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase if (changes.isEmpty()) { 6170e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase mChangesList.remove(changes); 6180e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase } 6190e0bfdb790fd9477e3531a1db92c3377057f83b7Chet Haase } 620235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase } 621235114f0ea0ae165e74a478f39bfc586392c53aaChet Haase 622a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar cancelAll(mRemoveAnimations); 623a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar cancelAll(mMoveAnimations); 624a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar cancelAll(mAddAnimations); 625a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar cancelAll(mChangeAnimations); 626ec93520d243d3eb3c6cddeaea7908d1b869bf367Dake Gu 627d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase dispatchAnimationsFinished(); 628d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 629d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 630a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar void cancelAll(List<ViewHolder> viewHolders) { 631a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar for (int i = viewHolders.size() - 1; i >= 0; i--) { 632a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar ViewCompat.animate(viewHolders.get(i).itemView).cancel(); 633a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar } 634a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar } 635a29fe6d4967a704799dc83d35ba80e426e9512cfYigit Boyar 636abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar /** 637abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar * {@inheritDoc} 638abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar * <p> 639abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar * If the payload list is not empty, DefaultItemAnimator returns <code>true</code>. 640abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar * When this is the case: 641abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar * <ul> 642abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar * <li>If you override {@link #animateChange(ViewHolder, ViewHolder, int, int, int, int)}, both 643abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar * ViewHolder arguments will be the same instance. 644abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar * </li> 645abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar * <li> 646abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar * If you are not overriding {@link #animateChange(ViewHolder, ViewHolder, int, int, int, int)}, 647abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar * then DefaultItemAnimator will call {@link #animateMove(ViewHolder, int, int, int, int)} and 648abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar * run a move animation instead. 649abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar * </li> 650abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar * </ul> 651abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar */ 652abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar @Override 653abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar public boolean canReuseUpdatedViewHolder(@NonNull ViewHolder viewHolder, 654abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar @NonNull List<Object> payloads) { 655abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar return !payloads.isEmpty() || super.canReuseUpdatedViewHolder(viewHolder, payloads); 656abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar } 657abea494886a17e7a51080ab5e9c2ca041c533353Yigit Boyar 658d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase private static class VpaListenerAdapter implements ViewPropertyAnimatorListener { 659d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 660d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public void onAnimationStart(View view) {} 661d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 662d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 663d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public void onAnimationEnd(View view) {} 664d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 665d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 666d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase public void onAnimationCancel(View view) {} 667e09e0b4ea04b6b6b0ef6c62979e8abdead0bf378Yigit Boyar } 668d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase} 669