2D Recents: Use a different task dismiss animation

am: 5df7667edb

Change-Id: Ib6186c663057d7a3c8d44ec13254f6c8b76ce3de
This commit is contained in:
Manu Cornet
2017-01-13 00:28:19 +00:00
committed by android-build-merger
2 changed files with 94 additions and 58 deletions

View File

@@ -390,68 +390,26 @@ public class TaskStackAnimationHelper {
/** /**
* Starts the delete animation for the specified {@link TaskView}. * Starts the delete animation for the specified {@link TaskView}.
*/ */
public void startDeleteTaskAnimation(final TaskView deleteTaskView, public void startDeleteTaskAnimation(final TaskView deleteTaskView, boolean gridLayout,
final ReferenceCountedTrigger postAnimationTrigger) { final ReferenceCountedTrigger postAnimationTrigger) {
TaskStackViewTouchHandler touchHandler = mStackView.getTouchHandler(); if (gridLayout) {
touchHandler.onBeginManualDrag(deleteTaskView); startTaskGridDeleteTaskAnimation(deleteTaskView, postAnimationTrigger);
} else {
postAnimationTrigger.increment(); startTaskStackDeleteTaskAnimation(deleteTaskView, postAnimationTrigger);
postAnimationTrigger.addLastDecrementRunnable(() -> { }
touchHandler.onChildDismissed(deleteTaskView);
});
final float dismissSize = touchHandler.getScaledDismissSize();
ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
animator.setDuration(400);
animator.addUpdateListener((animation) -> {
float progress = (Float) animation.getAnimatedValue();
deleteTaskView.setTranslationX(progress * dismissSize);
touchHandler.updateSwipeProgress(deleteTaskView, true, progress);
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
postAnimationTrigger.decrement();
}
});
animator.start();
} }
/** /**
* Starts the delete animation for all the {@link TaskView}s. * Starts the delete animation for all the {@link TaskView}s.
*/ */
public void startDeleteAllTasksAnimation(final List<TaskView> taskViews, public void startDeleteAllTasksAnimation(final List<TaskView> taskViews, boolean gridLayout,
final ReferenceCountedTrigger postAnimationTrigger) { final ReferenceCountedTrigger postAnimationTrigger) {
TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm(); if (gridLayout) {
for (int i = 0; i < taskViews.size(); i++) {
int offscreenXOffset = mStackView.getMeasuredWidth() - stackLayout.getTaskRect().left; startTaskGridDeleteTaskAnimation(taskViews.get(i), postAnimationTrigger);
}
int taskViewCount = taskViews.size(); } else {
for (int i = taskViewCount - 1; i >= 0; i--) { startTaskStackDeleteAllTasksAnimation(taskViews, postAnimationTrigger);
TaskView tv = taskViews.get(i);
int taskIndexFromFront = taskViewCount - i - 1;
int startDelay = taskIndexFromFront * DOUBLE_FRAME_OFFSET_MS;
// Disabling clipping with the stack while the view is animating away
tv.setClipViewInStack(false);
// Compose the new animation and transform and star the animation
AnimationProps taskAnimation = new AnimationProps(startDelay,
DISMISS_ALL_TASKS_DURATION, DISMISS_ALL_TRANSLATION_INTERPOLATOR,
new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
postAnimationTrigger.decrement();
// Re-enable clipping with the stack (we will reuse this view)
tv.setClipViewInStack(true);
}
});
postAnimationTrigger.increment();
mTmpTransform.fillIn(tv);
mTmpTransform.rect.offset(offscreenXOffset, 0);
mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
} }
} }
@@ -651,4 +609,80 @@ public class TaskStackAnimationHelper {
private int calculateStaggeredAnimDuration(int i) { private int calculateStaggeredAnimDuration(int i) {
return Math.max(100, 100 + ((i - 1) * 50)); return Math.max(100, 100 + ((i - 1) * 50));
} }
private void startTaskGridDeleteTaskAnimation(final TaskView deleteTaskView,
final ReferenceCountedTrigger postAnimationTrigger) {
postAnimationTrigger.increment();
postAnimationTrigger.addLastDecrementRunnable(() -> {
mStackView.getTouchHandler().onChildDismissed(deleteTaskView);
});
deleteTaskView.animate().setDuration(300).scaleX(0).scaleY(0).alpha(0).setListener(
new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
postAnimationTrigger.decrement();
}}).start();
}
private void startTaskStackDeleteTaskAnimation(final TaskView deleteTaskView,
final ReferenceCountedTrigger postAnimationTrigger) {
TaskStackViewTouchHandler touchHandler = mStackView.getTouchHandler();
touchHandler.onBeginManualDrag(deleteTaskView);
postAnimationTrigger.increment();
postAnimationTrigger.addLastDecrementRunnable(() -> {
touchHandler.onChildDismissed(deleteTaskView);
});
final float dismissSize = touchHandler.getScaledDismissSize();
ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
animator.setDuration(400);
animator.addUpdateListener((animation) -> {
float progress = (Float) animation.getAnimatedValue();
deleteTaskView.setTranslationX(progress * dismissSize);
touchHandler.updateSwipeProgress(deleteTaskView, true, progress);
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
postAnimationTrigger.decrement();
}
});
animator.start();
}
private void startTaskStackDeleteAllTasksAnimation(final List<TaskView> taskViews,
final ReferenceCountedTrigger postAnimationTrigger) {
TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
int offscreenXOffset = mStackView.getMeasuredWidth() - stackLayout.getTaskRect().left;
int taskViewCount = taskViews.size();
for (int i = taskViewCount - 1; i >= 0; i--) {
TaskView tv = taskViews.get(i);
int taskIndexFromFront = taskViewCount - i - 1;
int startDelay = taskIndexFromFront * DOUBLE_FRAME_OFFSET_MS;
// Disabling clipping with the stack while the view is animating away
tv.setClipViewInStack(false);
// Compose the new animation and transform and star the animation
AnimationProps taskAnimation = new AnimationProps(startDelay,
DISMISS_ALL_TASKS_DURATION, DISMISS_ALL_TRANSLATION_INTERPOLATOR,
new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
postAnimationTrigger.decrement();
// Re-enable clipping with the stack (we will reuse this view)
tv.setClipViewInStack(true);
}
});
postAnimationTrigger.increment();
mTmpTransform.fillIn(tv);
mTmpTransform.rect.offset(offscreenXOffset, 0);
mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
}
}
} }

View File

@@ -1754,13 +1754,15 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
public final void onBusEvent(DismissTaskViewEvent event) { public final void onBusEvent(DismissTaskViewEvent event) {
// For visible children, defer removing the task until after the animation // For visible children, defer removing the task until after the animation
mAnimationHelper.startDeleteTaskAnimation(event.taskView, event.getAnimationTrigger()); mAnimationHelper.startDeleteTaskAnimation(
event.taskView, useGridLayout(), event.getAnimationTrigger());
} }
public final void onBusEvent(final DismissAllTaskViewsEvent event) { public final void onBusEvent(final DismissAllTaskViewsEvent event) {
// Keep track of the tasks which will have their data removed // Keep track of the tasks which will have their data removed
ArrayList<Task> tasks = new ArrayList<>(mStack.getStackTasks()); ArrayList<Task> tasks = new ArrayList<>(mStack.getStackTasks());
mAnimationHelper.startDeleteAllTasksAnimation(getTaskViews(), event.getAnimationTrigger()); mAnimationHelper.startDeleteAllTasksAnimation(
getTaskViews(), useGridLayout(), event.getAnimationTrigger());
event.addPostAnimationCallback(new Runnable() { event.addPostAnimationCallback(new Runnable() {
@Override @Override
public void run() { public void run() {