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

Commit be8e696a authored by Winson's avatar Winson
Browse files

Allow animation controls for each animated property.

- Using onDrawForeground() instead of dispatchDraw()

Change-Id: Iae107a1ba14250f8c496264c60a29edc76df88e2
parent 70f0bf7d
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.views.TaskViewAnimation;
import com.android.systemui.recents.views.AnimationProps;

import java.util.ArrayList;
import java.util.Calendar;
@@ -224,7 +224,7 @@ public class RecentsHistoryAdapter extends RecyclerView.Adapter<RecentsHistoryAd
            if (row.getViewType() == TASK_ROW_VIEW_TYPE) {
                TaskRow taskRow = (TaskRow) row;
                Task task = taskRow.task;
                mStack.removeTask(task, TaskViewAnimation.IMMEDIATE);
                mStack.removeTask(task, AnimationProps.IMMEDIATE);
                EventBus.getDefault().send(new DeleteTaskDataEvent(task));
                i = removeTaskRow(i);
            }
@@ -304,7 +304,7 @@ public class RecentsHistoryAdapter extends RecyclerView.Adapter<RecentsHistoryAd
    public void onTaskRemoved(Task task, int position) {
        // Since this is removed from the history, we need to update the stack as well to ensure
        // that the model is correct. Since the stack is hidden, we can update it immediately.
        mStack.removeTask(task, TaskViewAnimation.IMMEDIATE);
        mStack.removeTask(task, AnimationProps.IMMEDIATE);
        removeTaskRow(position);
        if (mRows.isEmpty()) {
            dismissHistory();
+5 −5
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ import com.android.systemui.recents.misc.NamedCounter;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.views.DropTarget;
import com.android.systemui.recents.views.TaskViewAnimation;
import com.android.systemui.recents.views.AnimationProps;

import java.util.ArrayList;
import java.util.Collections;
@@ -228,12 +228,12 @@ public class TaskStack {
         * Notifies when a task has been removed from the stack.
         */
        void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask,
            Task newFrontMostTask, TaskViewAnimation animation);
            Task newFrontMostTask, AnimationProps animation);

        /**
         * Notifies when a task has been removed from the history.
         */
        void onHistoryTaskRemoved(TaskStack stack, Task removedTask, TaskViewAnimation animation);
        void onHistoryTaskRemoved(TaskStack stack, Task removedTask, AnimationProps animation);
    }

    /**
@@ -531,7 +531,7 @@ public class TaskStack {
     * Removes a task from the stack, with an additional {@param animation} hint to the callbacks on
     * how they should update themselves.
     */
    public void removeTask(Task t, TaskViewAnimation animation) {
    public void removeTask(Task t, AnimationProps animation) {
        if (mStackTaskList.contains(t)) {
            boolean wasFrontMostTask = (getStackFrontMostTask(false /* includeFreeform */) == t);
            removeTaskImpl(mStackTaskList, t);
@@ -575,7 +575,7 @@ public class TaskStack {
            if (!newTasksMap.containsKey(task.key)) {
                if (notifyStackChanges) {
                    mCb.onStackTaskRemoved(this, task, i == (taskCount - 1), null,
                            TaskViewAnimation.IMMEDIATE);
                            AnimationProps.IMMEDIATE);
                }
            }
            task.setGroup(null);
+3 −3
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.model.TaskStack.TaskStackCallbacks;
import com.android.systemui.recents.views.TaskViewAnimation;
import com.android.systemui.recents.views.AnimationProps;

import java.util.ArrayList;
import java.util.List;
@@ -137,7 +137,7 @@ public class TaskStackHorizontalGridView extends HorizontalGridView implements T

    @Override
    public void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask,
            Task newFrontMostTask, TaskViewAnimation animation) {
            Task newFrontMostTask, AnimationProps animation) {
        getAdapter().notifyItemRemoved(stack.getStackTasks().indexOf(removedTask));
        if (mFocusedTask == removedTask) {
            resetFocusedTask(removedTask);
@@ -152,7 +152,7 @@ public class TaskStackHorizontalGridView extends HorizontalGridView implements T
    }

    @Override
    public void onHistoryTaskRemoved(TaskStack stack, Task removedTask, TaskViewAnimation animation) {
    public void onHistoryTaskRemoved(TaskStack stack, Task removedTask, AnimationProps animation) {
        //No history task on tv
    }
}
+227 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.systemui.recents.views;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.annotation.IntDef;
import android.util.SparseArray;
import android.util.SparseLongArray;
import android.view.View;
import android.view.animation.Interpolator;

import com.android.systemui.Interpolators;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;

/**
 * The generic set of animation properties to animate a {@link View}. The animation can have
 * different interpolators, start delays and durations for each of the different properties.
 */
public class AnimationProps {

    public static final AnimationProps IMMEDIATE = new AnimationProps(0, Interpolators.LINEAR);

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({ALL, TRANSLATION_X, TRANSLATION_Y, TRANSLATION_Z, ALPHA, SCALE, BOUNDS})
    public @interface PropType {}

    public static final int ALL = 0;
    public static final int TRANSLATION_X = 1;
    public static final int TRANSLATION_Y = 2;
    public static final int TRANSLATION_Z = 3;
    public static final int ALPHA = 4;
    public static final int SCALE = 5;
    public static final int BOUNDS = 6;

    private SparseLongArray mPropStartDelay;
    private SparseLongArray mPropDuration;
    private SparseArray<Interpolator> mPropInterpolators;
    private Animator.AnimatorListener mListener;

    /**
     * The builder constructor.
     */
    public AnimationProps() {}

    /**
     * Creates an animation with a default {@param duration} and {@param interpolator} for all
     * properties in this animation.
     */
    public AnimationProps(int duration, Interpolator interpolator) {
        this(0, duration, interpolator, null);
    }

    /**
     * Creates an animation with a default {@param duration} and {@param interpolator} for all
     * properties in this animation.
     */
    public AnimationProps(int duration, Interpolator interpolator,
            Animator.AnimatorListener listener) {
        this(0, duration, interpolator, listener);
    }

    /**
     * Creates an animation with a default {@param startDelay}, {@param duration} and
     * {@param interpolator} for all properties in this animation.
     */
    public AnimationProps(int startDelay, int duration, Interpolator interpolator) {
        this(startDelay, duration, interpolator, null);
    }

    /**
     * Creates an animation with a default {@param startDelay}, {@param duration} and
     * {@param interpolator} for all properties in this animation.
     */
    public AnimationProps(int startDelay, int duration, Interpolator interpolator,
            Animator.AnimatorListener listener) {
        setStartDelay(ALL, startDelay);
        setDuration(ALL, duration);
        setInterpolator(ALL, interpolator);
        setListener(listener);
    }

    /**
     * Creates a new {@link AnimatorSet} that will animate the given animators.  Callers need to
     * manually apply the individual animation properties for each of the animators respectively.
     */
    public AnimatorSet createAnimator(List<Animator> animators) {
        AnimatorSet anim = new AnimatorSet();
        if (mListener != null) {
            anim.addListener(mListener);
        }
        anim.playTogether(animators);
        return anim;
    }

    /**
     * Applies the specific start delay, duration and interpolator to the given {@param animator}
     * for the specified {@param propertyType}.
     */
    public <T extends Animator> T apply(@PropType int propertyType, T animator) {
        animator.setStartDelay(getStartDelay(propertyType));
        animator.setDuration(getDuration(propertyType));
        animator.setInterpolator(getInterpolator(propertyType));
        return animator;
    }

    /**
     * Sets a start delay for a specific property.
     */
    public AnimationProps setStartDelay(@PropType int propertyType, int startDelay) {
        if (mPropStartDelay == null) {
            mPropStartDelay = new SparseLongArray();
        }
        mPropStartDelay.append(propertyType, startDelay);
        return this;
    }

    /**
     * Returns the start delay for a specific property.
     */
    public long getStartDelay(@PropType int propertyType) {
        if (mPropStartDelay != null) {
            long startDelay = mPropStartDelay.get(propertyType, -1);
            if (startDelay != -1) {
                return startDelay;
            }
            return mPropStartDelay.get(ALL, 0);
        }
        return 0;
    }

    /**
     * Sets a duration for a specific property.
     */
    public AnimationProps setDuration(@PropType int propertyType, int duration) {
        if (mPropDuration == null) {
            mPropDuration = new SparseLongArray();
        }
        mPropDuration.append(propertyType, duration);
        return this;
    }

    /**
     * Returns the duration for a specific property.
     */
    public long getDuration(@PropType int propertyType) {
        if (mPropDuration != null) {
            long duration = mPropDuration.get(propertyType, -1);
            if (duration != -1) {
                return duration;
            }
            return mPropDuration.get(ALL, 0);
        }
        return 0;
    }

    /**
     * Sets an interpolator for a specific property.
     */
    public AnimationProps setInterpolator(@PropType int propertyType, Interpolator interpolator) {
        if (mPropInterpolators == null) {
            mPropInterpolators = new SparseArray<>();
        }
        mPropInterpolators.append(propertyType, interpolator);
        return this;
    }

    /**
     * Returns the interpolator for a specific property, falling back to the general interpolator
     * if there is no specific property interpolator.
     */
    public Interpolator getInterpolator(@PropType int propertyType) {
        if (mPropInterpolators != null) {
            Interpolator interp = mPropInterpolators.get(propertyType);
            if (interp != null) {
                return interp;
            }
            return mPropInterpolators.get(ALL, Interpolators.LINEAR);
        }
        return Interpolators.LINEAR;
    }

    /**
     * Sets an animator listener for this animation.
     */
    public AnimationProps setListener(Animator.AnimatorListener listener) {
        mListener = listener;
        return this;
    }

    /**
     * Returns the animator listener for this animation.
     */
    public Animator.AnimatorListener getListener() {
        return mListener;
    }

    /**
     * Returns whether this animation has any duration.
     */
    public boolean isImmediate() {
        int count = mPropDuration.size();
        for (int i = 0; i < count; i++) {
            if (mPropDuration.valueAt(i) > 0) {
                return false;
            }
        }
        return true;
    }
}
+5 −4
Original line number Diff line number Diff line
@@ -497,8 +497,9 @@ public class RecentsView extends FrameLayout {
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
    public void onDrawForeground(Canvas canvas) {
        super.onDrawForeground(canvas);

        ArrayList<TaskStack.DockState> visDockStates = mTouchHandler.getVisibleDockStates();
        for (int i = visDockStates.size() - 1; i >= 0; i--) {
            Drawable d = visDockStates.get(i).viewState.dockAreaOverlay;
@@ -588,7 +589,7 @@ public class RecentsView extends FrameLayout {
            tmpTransform.scale = 1f;
            tmpTransform.rect.set(taskViewRect);
            mTaskStackView.updateTaskViewToTransform(event.taskView, tmpTransform,
                    new TaskViewAnimation(125, Interpolators.ALPHA_OUT,
                    new AnimationProps(125, Interpolators.ALPHA_OUT,
                            new AnimatorListenerAdapter() {
                                @Override
                                public void onAnimationEnd(Animator animation) {
@@ -598,7 +599,7 @@ public class RecentsView extends FrameLayout {
                                            event.task.key.id, dockState.createMode);

                                    // Animate the stack accordingly
                                    TaskViewAnimation stackAnim = new TaskViewAnimation(
                                    AnimationProps stackAnim = new AnimationProps(
                                            TaskStackView.DEFAULT_SYNC_STACK_DURATION,
                                            Interpolators.FAST_OUT_SLOW_IN);
                                    mTaskStackView.getStack().removeTask(event.task, stackAnim);
Loading