diff options
Diffstat (limited to 'src/com/android/car/dialer/StrequentsItemAnimator.java')
-rw-r--r-- | src/com/android/car/dialer/StrequentsItemAnimator.java | 637 |
1 files changed, 0 insertions, 637 deletions
diff --git a/src/com/android/car/dialer/StrequentsItemAnimator.java b/src/com/android/car/dialer/StrequentsItemAnimator.java deleted file mode 100644 index 23e8b1d8..00000000 --- a/src/com/android/car/dialer/StrequentsItemAnimator.java +++ /dev/null @@ -1,637 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.car.dialer; - -import android.support.v4.view.ViewCompat; -import android.support.v4.view.ViewPropertyAnimatorCompat; -import android.support.v4.view.ViewPropertyAnimatorListener; -import android.support.v7.widget.RecyclerView.ViewHolder; -import android.support.v7.widget.SimpleItemAnimator; -import android.view.View; - -import java.util.ArrayList; -import java.util.List; - -/** - * Branch from {@link android.support.v7.widget.DefaultItemAnimator} with changes on - * {@link #animateAddImpl}, {@link #animateAdd} and {@link #animateRemoveImpl}. - */ -public class StrequentsItemAnimator extends SimpleItemAnimator { - private static final boolean DEBUG = false; - - private ArrayList<ViewHolder> mPendingRemovals = new ArrayList<>(); - private ArrayList<ViewHolder> mPendingAdditions = new ArrayList<>(); - private ArrayList<MoveInfo> mPendingMoves = new ArrayList<>(); - private ArrayList<ChangeInfo> mPendingChanges = new ArrayList<>(); - - private ArrayList<ArrayList<ViewHolder>> mAdditionsList = new ArrayList<>(); - private ArrayList<ArrayList<MoveInfo>> mMovesList = new ArrayList<>(); - private ArrayList<ArrayList<ChangeInfo>> mChangesList = new ArrayList<>(); - - private ArrayList<ViewHolder> mAddAnimations = new ArrayList<>(); - private ArrayList<ViewHolder> mMoveAnimations = new ArrayList<>(); - private ArrayList<ViewHolder> mRemoveAnimations = new ArrayList<>(); - private ArrayList<ViewHolder> mChangeAnimations = new ArrayList<>(); - - private static class MoveInfo { - public ViewHolder holder; - public int fromX, fromY, toX, toY; - - private MoveInfo(ViewHolder holder, int fromX, int fromY, int toX, int toY) { - this.holder = holder; - this.fromX = fromX; - this.fromY = fromY; - this.toX = toX; - this.toY = toY; - } - } - - private static class ChangeInfo { - public ViewHolder oldHolder, newHolder; - public int fromX, fromY, toX, toY; - private ChangeInfo(ViewHolder oldHolder, ViewHolder newHolder) { - this.oldHolder = oldHolder; - this.newHolder = newHolder; - } - - private ChangeInfo(ViewHolder oldHolder, ViewHolder newHolder, - int fromX, int fromY, int toX, int toY) { - this(oldHolder, newHolder); - this.fromX = fromX; - this.fromY = fromY; - this.toX = toX; - this.toY = toY; - } - - @Override - public String toString() { - return "ChangeInfo{" + - "oldHolder=" + oldHolder + - ", newHolder=" + newHolder + - ", fromX=" + fromX + - ", fromY=" + fromY + - ", toX=" + toX + - ", toY=" + toY + - '}'; - } - } - - @Override - public void runPendingAnimations() { - boolean removalsPending = !mPendingRemovals.isEmpty(); - boolean movesPending = !mPendingMoves.isEmpty(); - boolean changesPending = !mPendingChanges.isEmpty(); - boolean additionsPending = !mPendingAdditions.isEmpty(); - if (!removalsPending && !movesPending && !additionsPending && !changesPending) { - // nothing to animate - return; - } - // First, remove stuff - for (ViewHolder holder : mPendingRemovals) { - animateRemoveImpl(holder); - } - mPendingRemovals.clear(); - // Next, move stuff - if (movesPending) { - final ArrayList<MoveInfo> moves = new ArrayList<MoveInfo>(); - moves.addAll(mPendingMoves); - mMovesList.add(moves); - mPendingMoves.clear(); - Runnable mover = new Runnable() { - @Override - public void run() { - for (MoveInfo moveInfo : moves) { - animateMoveImpl(moveInfo.holder, moveInfo.fromX, moveInfo.fromY, - moveInfo.toX, moveInfo.toY); - } - moves.clear(); - mMovesList.remove(moves); - } - }; - if (removalsPending) { - View view = moves.get(0).holder.itemView; - ViewCompat.postOnAnimationDelayed(view, mover, getRemoveDuration()); - } else { - mover.run(); - } - } - // Next, change stuff, to run in parallel with move animations - if (changesPending) { - final ArrayList<ChangeInfo> changes = new ArrayList<ChangeInfo>(); - changes.addAll(mPendingChanges); - mChangesList.add(changes); - mPendingChanges.clear(); - Runnable changer = new Runnable() { - @Override - public void run() { - for (ChangeInfo change : changes) { - animateChangeImpl(change); - } - changes.clear(); - mChangesList.remove(changes); - } - }; - if (removalsPending) { - ViewHolder holder = changes.get(0).oldHolder; - ViewCompat.postOnAnimationDelayed(holder.itemView, changer, getRemoveDuration()); - } else { - changer.run(); - } - } - // Next, add stuff - if (additionsPending) { - final ArrayList<ViewHolder> additions = new ArrayList<ViewHolder>(); - additions.addAll(mPendingAdditions); - mAdditionsList.add(additions); - mPendingAdditions.clear(); - Runnable adder = new Runnable() { - public void run() { - for (ViewHolder holder : additions) { - animateAddImpl(holder); - } - additions.clear(); - mAdditionsList.remove(additions); - } - }; - if (removalsPending || movesPending || changesPending) { - long removeDuration = removalsPending ? getRemoveDuration() : 0; - long moveDuration = movesPending ? getMoveDuration() : 0; - long changeDuration = changesPending ? getChangeDuration() : 0; - long totalDelay = removeDuration + Math.max(moveDuration, changeDuration); - View view = additions.get(0).itemView; - ViewCompat.postOnAnimationDelayed(view, adder, totalDelay); - } else { - adder.run(); - } - } - } - - @Override - public boolean animateRemove(final ViewHolder holder) { - endAnimation(holder); - mPendingRemovals.add(holder); - return true; - } - - private void animateRemoveImpl(final ViewHolder holder) { - // Animate on the content if it's CallLogViewHolder. - final View view = holder instanceof CallLogViewHolder ? - ((CallLogViewHolder) holder).container : holder.itemView; - final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view); - mRemoveAnimations.add(holder); - animation.setDuration(getRemoveDuration()) - .alpha(0).setListener(new VpaListenerAdapter() { - @Override - public void onAnimationStart(View view) { - dispatchRemoveStarting(holder); - } - - @Override - public void onAnimationEnd(View view) { - animation.setListener(null); - ViewCompat.setAlpha(view, 1); - dispatchRemoveFinished(holder); - mRemoveAnimations.remove(holder); - dispatchFinishedWhenDone(); - } - }).start(); - } - - @Override - public boolean animateAdd(final ViewHolder holder) { - endAnimation(holder); - // for CallLogViewHolder, instead of fade out the whole card, fade out only the content. - if (holder instanceof CallLogViewHolder) { - ViewCompat.setAlpha(((CallLogViewHolder) holder).container, 0); - } else { - ViewCompat.setAlpha(holder.itemView, 0); - } - mPendingAdditions.add(holder); - return true; - } - - private void animateAddImpl(final ViewHolder holder) { - // Animate on the content if it's CallLogViewHolder. - final View view = holder instanceof CallLogViewHolder ? - ((CallLogViewHolder) holder).container : holder.itemView; - final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view); - mAddAnimations.add(holder); - animation.alpha(1).setDuration(getAddDuration()). - setListener(new VpaListenerAdapter() { - @Override - public void onAnimationStart(View view) { - dispatchAddStarting(holder); - } - @Override - public void onAnimationCancel(View view) { - ViewCompat.setAlpha(view, 1); - } - - @Override - public void onAnimationEnd(View view) { - animation.setListener(null); - dispatchAddFinished(holder); - mAddAnimations.remove(holder); - dispatchFinishedWhenDone(); - } - }).start(); - } - - @Override - public boolean animateMove(final ViewHolder holder, int fromX, int fromY, - int toX, int toY) { - final View view = holder.itemView; - fromX += ViewCompat.getTranslationX(holder.itemView); - fromY += ViewCompat.getTranslationY(holder.itemView); - endAnimation(holder); - int deltaX = toX - fromX; - int deltaY = toY - fromY; - if (deltaX == 0 && deltaY == 0) { - dispatchMoveFinished(holder); - return false; - } - if (deltaX != 0) { - ViewCompat.setTranslationX(view, -deltaX); - } - if (deltaY != 0) { - ViewCompat.setTranslationY(view, -deltaY); - } - mPendingMoves.add(new MoveInfo(holder, fromX, fromY, toX, toY)); - return true; - } - - private void animateMoveImpl(final ViewHolder holder, int fromX, int fromY, int toX, int toY) { - final View view = holder.itemView; - final int deltaX = toX - fromX; - final int deltaY = toY - fromY; - if (deltaX != 0) { - ViewCompat.animate(view).translationX(0); - } - if (deltaY != 0) { - ViewCompat.animate(view).translationY(0); - } - // TODO: make EndActions end listeners instead, since end actions aren't called when - // vpas are canceled (and can't end them. why?) - // need listener functionality in VPACompat for this. Ick. - final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view); - mMoveAnimations.add(holder); - animation.setDuration(getMoveDuration()).setListener(new VpaListenerAdapter() { - @Override - public void onAnimationStart(View view) { - dispatchMoveStarting(holder); - } - @Override - public void onAnimationCancel(View view) { - if (deltaX != 0) { - ViewCompat.setTranslationX(view, 0); - } - if (deltaY != 0) { - ViewCompat.setTranslationY(view, 0); - } - } - @Override - public void onAnimationEnd(View view) { - animation.setListener(null); - dispatchMoveFinished(holder); - mMoveAnimations.remove(holder); - dispatchFinishedWhenDone(); - } - }).start(); - } - - @Override - public boolean animateChange(ViewHolder oldHolder, ViewHolder newHolder, - int fromX, int fromY, int toX, int toY) { - final float prevTranslationX = ViewCompat.getTranslationX(oldHolder.itemView); - final float prevTranslationY = ViewCompat.getTranslationY(oldHolder.itemView); - final float prevAlpha = ViewCompat.getAlpha(oldHolder.itemView); - endAnimation(oldHolder); - int deltaX = (int) (toX - fromX - prevTranslationX); - int deltaY = (int) (toY - fromY - prevTranslationY); - // recover prev translation state after ending animation - ViewCompat.setTranslationX(oldHolder.itemView, prevTranslationX); - ViewCompat.setTranslationY(oldHolder.itemView, prevTranslationY); - ViewCompat.setAlpha(oldHolder.itemView, prevAlpha); - if (newHolder != null && newHolder.itemView != null) { - // carry over translation values - endAnimation(newHolder); - ViewCompat.setTranslationX(newHolder.itemView, -deltaX); - ViewCompat.setTranslationY(newHolder.itemView, -deltaY); - ViewCompat.setAlpha(newHolder.itemView, 0); - } - mPendingChanges.add(new ChangeInfo(oldHolder, newHolder, fromX, fromY, toX, toY)); - return true; - } - - private void animateChangeImpl(final ChangeInfo changeInfo) { - final ViewHolder holder = changeInfo.oldHolder; - final View view = holder == null ? null : holder.itemView; - final ViewHolder newHolder = changeInfo.newHolder; - final View newView = newHolder != null ? newHolder.itemView : null; - if (view != null) { - final ViewPropertyAnimatorCompat oldViewAnim = ViewCompat.animate(view).setDuration( - getChangeDuration()); - mChangeAnimations.add(changeInfo.oldHolder); - oldViewAnim.translationX(changeInfo.toX - changeInfo.fromX); - oldViewAnim.translationY(changeInfo.toY - changeInfo.fromY); - oldViewAnim.alpha(0).setListener(new VpaListenerAdapter() { - @Override - public void onAnimationStart(View view) { - dispatchChangeStarting(changeInfo.oldHolder, true); - } - - @Override - public void onAnimationEnd(View view) { - oldViewAnim.setListener(null); - ViewCompat.setAlpha(view, 1); - ViewCompat.setTranslationX(view, 0); - ViewCompat.setTranslationY(view, 0); - dispatchChangeFinished(changeInfo.oldHolder, true); - mChangeAnimations.remove(changeInfo.oldHolder); - dispatchFinishedWhenDone(); - } - }).start(); - } - if (newView != null) { - final ViewPropertyAnimatorCompat newViewAnimation = ViewCompat.animate(newView); - mChangeAnimations.add(changeInfo.newHolder); - newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()). - alpha(1).setListener(new VpaListenerAdapter() { - @Override - public void onAnimationStart(View view) { - dispatchChangeStarting(changeInfo.newHolder, false); - } - @Override - public void onAnimationEnd(View view) { - newViewAnimation.setListener(null); - ViewCompat.setAlpha(newView, 1); - ViewCompat.setTranslationX(newView, 0); - ViewCompat.setTranslationY(newView, 0); - dispatchChangeFinished(changeInfo.newHolder, false); - mChangeAnimations.remove(changeInfo.newHolder); - dispatchFinishedWhenDone(); - } - }).start(); - } - } - - private void endChangeAnimation(List<ChangeInfo> infoList, ViewHolder item) { - for (int i = infoList.size() - 1; i >= 0; i--) { - ChangeInfo changeInfo = infoList.get(i); - if (endChangeAnimationIfNecessary(changeInfo, item)) { - if (changeInfo.oldHolder == null && changeInfo.newHolder == null) { - infoList.remove(changeInfo); - } - } - } - } - - private void endChangeAnimationIfNecessary(ChangeInfo changeInfo) { - if (changeInfo.oldHolder != null) { - endChangeAnimationIfNecessary(changeInfo, changeInfo.oldHolder); - } - if (changeInfo.newHolder != null) { - endChangeAnimationIfNecessary(changeInfo, changeInfo.newHolder); - } - } - private boolean endChangeAnimationIfNecessary(ChangeInfo changeInfo, ViewHolder item) { - boolean oldItem = false; - if (changeInfo.newHolder == item) { - changeInfo.newHolder = null; - } else if (changeInfo.oldHolder == item) { - changeInfo.oldHolder = null; - oldItem = true; - } else { - return false; - } - ViewCompat.setAlpha(item.itemView, 1); - ViewCompat.setTranslationX(item.itemView, 0); - ViewCompat.setTranslationY(item.itemView, 0); - dispatchChangeFinished(item, oldItem); - return true; - } - - @Override - public void endAnimation(ViewHolder item) { - final View view = item.itemView; - // this will trigger end callback which should set properties to their target values. - ViewCompat.animate(view).cancel(); - // TODO if some other animations are chained to end, how do we cancel them as well? - for (int i = mPendingMoves.size() - 1; i >= 0; i--) { - MoveInfo moveInfo = mPendingMoves.get(i); - if (moveInfo.holder == item) { - ViewCompat.setTranslationY(view, 0); - ViewCompat.setTranslationX(view, 0); - dispatchMoveFinished(item); - mPendingMoves.remove(i); - } - } - endChangeAnimation(mPendingChanges, item); - if (mPendingRemovals.remove(item)) { - ViewCompat.setAlpha(view, 1); - dispatchRemoveFinished(item); - } - if (mPendingAdditions.remove(item)) { - ViewCompat.setAlpha(view, 1); - dispatchAddFinished(item); - } - - for (int i = mChangesList.size() - 1; i >= 0; i--) { - ArrayList<ChangeInfo> changes = mChangesList.get(i); - endChangeAnimation(changes, item); - if (changes.isEmpty()) { - mChangesList.remove(i); - } - } - for (int i = mMovesList.size() - 1; i >= 0; i--) { - ArrayList<MoveInfo> moves = mMovesList.get(i); - for (int j = moves.size() - 1; j >= 0; j--) { - MoveInfo moveInfo = moves.get(j); - if (moveInfo.holder == item) { - ViewCompat.setTranslationY(view, 0); - ViewCompat.setTranslationX(view, 0); - dispatchMoveFinished(item); - moves.remove(j); - if (moves.isEmpty()) { - mMovesList.remove(i); - } - break; - } - } - } - for (int i = mAdditionsList.size() - 1; i >= 0; i--) { - ArrayList<ViewHolder> additions = mAdditionsList.get(i); - if (additions.remove(item)) { - ViewCompat.setAlpha(view, 1); - dispatchAddFinished(item); - if (additions.isEmpty()) { - mAdditionsList.remove(i); - } - } - } - - // animations should be ended by the cancel above. - if (mRemoveAnimations.remove(item) && DEBUG) { - throw new IllegalStateException("after animation is cancelled, item should not be in " - + "mRemoveAnimations list"); - } - - if (mAddAnimations.remove(item) && DEBUG) { - throw new IllegalStateException("after animation is cancelled, item should not be in " - + "mAddAnimations list"); - } - - if (mChangeAnimations.remove(item) && DEBUG) { - throw new IllegalStateException("after animation is cancelled, item should not be in " - + "mChangeAnimations list"); - } - - if (mMoveAnimations.remove(item) && DEBUG) { - throw new IllegalStateException("after animation is cancelled, item should not be in " - + "mMoveAnimations list"); - } - dispatchFinishedWhenDone(); - } - - @Override - public boolean isRunning() { - return (!mPendingAdditions.isEmpty() || - !mPendingChanges.isEmpty() || - !mPendingMoves.isEmpty() || - !mPendingRemovals.isEmpty() || - !mMoveAnimations.isEmpty() || - !mRemoveAnimations.isEmpty() || - !mAddAnimations.isEmpty() || - !mChangeAnimations.isEmpty() || - !mMovesList.isEmpty() || - !mAdditionsList.isEmpty() || - !mChangesList.isEmpty()); - } - - /** - * Check the state of currently pending and running animations. If there are none - * pending/running, call {@link #dispatchAnimationsFinished()} to notify any - * listeners. - */ - private void dispatchFinishedWhenDone() { - if (!isRunning()) { - dispatchAnimationsFinished(); - } - } - - @Override - public void endAnimations() { - int count = mPendingMoves.size(); - for (int i = count - 1; i >= 0; i--) { - MoveInfo item = mPendingMoves.get(i); - View view = item.holder.itemView; - ViewCompat.setTranslationY(view, 0); - ViewCompat.setTranslationX(view, 0); - dispatchMoveFinished(item.holder); - mPendingMoves.remove(i); - } - count = mPendingRemovals.size(); - for (int i = count - 1; i >= 0; i--) { - ViewHolder item = mPendingRemovals.get(i); - dispatchRemoveFinished(item); - mPendingRemovals.remove(i); - } - count = mPendingAdditions.size(); - for (int i = count - 1; i >= 0; i--) { - ViewHolder item = mPendingAdditions.get(i); - View view = item.itemView; - ViewCompat.setAlpha(view, 1); - dispatchAddFinished(item); - mPendingAdditions.remove(i); - } - count = mPendingChanges.size(); - for (int i = count - 1; i >= 0; i--) { - endChangeAnimationIfNecessary(mPendingChanges.get(i)); - } - mPendingChanges.clear(); - if (!isRunning()) { - return; - } - - int listCount = mMovesList.size(); - for (int i = listCount - 1; i >= 0; i--) { - ArrayList<MoveInfo> moves = mMovesList.get(i); - count = moves.size(); - for (int j = count - 1; j >= 0; j--) { - MoveInfo moveInfo = moves.get(j); - ViewHolder item = moveInfo.holder; - View view = item.itemView; - ViewCompat.setTranslationY(view, 0); - ViewCompat.setTranslationX(view, 0); - dispatchMoveFinished(moveInfo.holder); - moves.remove(j); - if (moves.isEmpty()) { - mMovesList.remove(moves); - } - } - } - listCount = mAdditionsList.size(); - for (int i = listCount - 1; i >= 0; i--) { - ArrayList<ViewHolder> additions = mAdditionsList.get(i); - count = additions.size(); - for (int j = count - 1; j >= 0; j--) { - ViewHolder item = additions.get(j); - View view = item.itemView; - ViewCompat.setAlpha(view, 1); - dispatchAddFinished(item); - additions.remove(j); - if (additions.isEmpty()) { - mAdditionsList.remove(additions); - } - } - } - listCount = mChangesList.size(); - for (int i = listCount - 1; i >= 0; i--) { - ArrayList<ChangeInfo> changes = mChangesList.get(i); - count = changes.size(); - for (int j = count - 1; j >= 0; j--) { - endChangeAnimationIfNecessary(changes.get(j)); - if (changes.isEmpty()) { - mChangesList.remove(changes); - } - } - } - - cancelAll(mRemoveAnimations); - cancelAll(mMoveAnimations); - cancelAll(mAddAnimations); - cancelAll(mChangeAnimations); - - dispatchAnimationsFinished(); - } - - void cancelAll(List<ViewHolder> viewHolders) { - for (int i = viewHolders.size() - 1; i >= 0; i--) { - ViewCompat.animate(viewHolders.get(i).itemView).cancel(); - } - } - - private static class VpaListenerAdapter implements ViewPropertyAnimatorListener { - @Override - public void onAnimationStart(View view) {} - - @Override - public void onAnimationEnd(View view) {} - - @Override - public void onAnimationCancel(View view) {} - }; -} |