Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5df7667e authored by Manu Cornet's avatar Manu Cornet
Browse files

2D Recents: Use a different task dismiss animation

Bug: 32101881
Test: Checked layout and animation on local sw600dp device
Change-Id: Ic92a6a5aa0c25fac5553de9a0145a0b39ae6ddb1
parent a00c2356
Loading
Loading
Loading
Loading
+90 −56
Original line number Diff line number Diff line
@@ -390,68 +390,26 @@ public class TaskStackAnimationHelper {
    /**
     * 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) {
        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();
        if (gridLayout) {
            startTaskGridDeleteTaskAnimation(deleteTaskView, postAnimationTrigger);
        } else {
            startTaskStackDeleteTaskAnimation(deleteTaskView, postAnimationTrigger);
        }
        });
        animator.start();
    }

    /**
     * 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) {
        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);
        if (gridLayout) {
            for (int i = 0; i < taskViews.size(); i++) {
                startTaskGridDeleteTaskAnimation(taskViews.get(i), postAnimationTrigger);
            }
            });
            postAnimationTrigger.increment();

            mTmpTransform.fillIn(tv);
            mTmpTransform.rect.offset(offscreenXOffset, 0);
            mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
        } else {
            startTaskStackDeleteAllTasksAnimation(taskViews, postAnimationTrigger);
        }
    }

@@ -651,4 +609,80 @@ public class TaskStackAnimationHelper {
    private int calculateStaggeredAnimDuration(int i) {
        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);
        }
    }
}
+4 −2
Original line number Diff line number Diff line
@@ -1754,13 +1754,15 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal

    public final void onBusEvent(DismissTaskViewEvent event) {
        // 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) {
        // Keep track of the tasks which will have their data removed
        ArrayList<Task> tasks = new ArrayList<>(mStack.getStackTasks());
        mAnimationHelper.startDeleteAllTasksAnimation(getTaskViews(), event.getAnimationTrigger());
        mAnimationHelper.startDeleteAllTasksAnimation(
                getTaskViews(), useGridLayout(), event.getAnimationTrigger());
        event.addPostAnimationCallback(new Runnable() {
            @Override
            public void run() {