diff options
| author | 2016-02-02 20:28:14 +0000 | |
|---|---|---|
| committer | 2016-02-02 20:28:14 +0000 | |
| commit | b52567d6a3197718a912b83799b92c47fe6a482d (patch) | |
| tree | 64f1ea8ab17363c2d7bfb3c810678787e042e663 | |
| parent | b9427f34d81bc6f23a1bcefb43675be0627c699d (diff) | |
| parent | 50448630a49a9602eb53561d1c022890d07449d0 (diff) | |
Merge changes Idedf0045,Iae107a1b,Id798cc39
* changes:
Tweaking enter from/exit to home animations.
Allow animation controls for each animated property.
Fixing regression in animation of drag task.
14 files changed, 422 insertions, 226 deletions
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index ebe0d973e752..e8df01b19415 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -159,18 +159,6 @@ in from the bottom of the screen. --> <integer name="recents_enter_from_home_transition_duration">100</integer> - <!-- The duration for animating the task from the bottom of the screen when transitioning - from home. --> - <integer name="recents_task_enter_from_home_duration">225</integer> - - <!-- The stagger for each task when animating the task from the bottom of the screen when - transitioning from home. --> - <integer name="recents_task_enter_from_home_stagger_delay">12</integer> - - <!-- The duration of the animation of the tasks to the bottom of the screen when leaving - Recents to go back to the Launcher. --> - <integer name="recents_task_exit_to_home_duration">225</integer> - <!-- The min animation duration for animating the nav bar scrim in. --> <integer name="recents_nav_bar_scrim_enter_duration">400</integer> diff --git a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java index e288878a15ff..ee3eb02c8a38 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java @@ -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(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java index aa8efa711550..1f91dceb3e99 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java @@ -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); diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java index 2d4174296e7b..58ec8521ec7b 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java @@ -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 } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/AnimationProps.java b/packages/SystemUI/src/com/android/systemui/recents/views/AnimationProps.java new file mode 100644 index 000000000000..93878c52d6de --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recents/views/AnimationProps.java @@ -0,0 +1,227 @@ +/* + * 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; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java index e2ff52cefd23..5e113b997bce 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -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; @@ -530,8 +531,7 @@ public class RecentsView extends FrameLayout { public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) { // Hide the history button - int taskViewExitToHomeDuration = getResources().getInteger( - R.integer.recents_task_exit_to_home_duration); + int taskViewExitToHomeDuration = TaskStackAnimationHelper.EXIT_TO_HOME_TRANSLATION_DURATION; hideHistoryButton(taskViewExitToHomeDuration, false /* translate */); animateBackgroundScrim(0f, taskViewExitToHomeDuration); } @@ -588,7 +588,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 +598,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); @@ -646,9 +646,8 @@ public class RecentsView extends FrameLayout { public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) { RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState(); if (!launchState.launchedFromAppWithThumbnail && mStack.getTaskCount() > 0) { - int taskViewEnterFromHomeDuration = getResources().getInteger( - R.integer.recents_task_enter_from_home_duration); - animateBackgroundScrim(DEFAULT_SCRIM_ALPHA, taskViewEnterFromHomeDuration); + animateBackgroundScrim(DEFAULT_SCRIM_ALPHA, + TaskStackAnimationHelper.ENTER_FROM_HOME_TRANSLATION_DURATION); } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java index 682c29820ce3..0eae183e58d6 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java @@ -20,8 +20,10 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.content.Context; import android.content.res.Resources; +import android.graphics.Path; import android.graphics.RectF; import android.view.View; +import android.view.animation.PathInterpolator; import com.android.systemui.Interpolators; import com.android.systemui.R; @@ -63,6 +65,22 @@ public class TaskStackAnimationHelper { ReferenceCountedTrigger postAnimationTrigger); } + private static final int FRAME_OFFSET_MS = 16; + + public static final int ENTER_FROM_HOME_ALPHA_DURATION = 100; + public static final int ENTER_FROM_HOME_TRANSLATION_DURATION = 333; + private static final PathInterpolator ENTER_FROM_HOME_TRANSLATION_INTERPOLATOR = + new PathInterpolator(0, 0, 0, 1f); + private static final PathInterpolator ENTER_FROM_HOME_ALPHA_INTERPOLATOR = + new PathInterpolator(0, 0, 0.2f, 1f); + + public static final int EXIT_TO_HOME_ALPHA_DURATION = 100; + public static final int EXIT_TO_HOME_TRANSLATION_DURATION = 150; + private static final PathInterpolator EXIT_TO_HOME_TRANSLATION_INTERPOLATOR = + new PathInterpolator(0.8f, 0, 0.6f, 1f); + private static final PathInterpolator EXIT_TO_HOME_ALPHA_INTERPOLATOR = + new PathInterpolator(0.4f, 0, 1f, 1f); + private TaskStackView mStackView; private TaskViewTransform mTmpTransform = new TaskViewTransform(); @@ -157,15 +175,12 @@ public class TaskStackAnimationHelper { R.integer.recents_task_enter_from_app_duration); int taskViewEnterFromAffiliatedAppDuration = res.getInteger( R.integer.recents_task_enter_from_affiliated_app_duration); - int taskViewEnterFromHomeDuration = res.getInteger( - R.integer.recents_task_enter_from_home_duration); - int taskViewEnterFromHomeStaggerDelay = res.getInteger( - R.integer.recents_task_enter_from_home_stagger_delay); // Create enter animations for each of the views from front to back List<TaskView> taskViews = mStackView.getTaskViews(); int taskViewCount = taskViews.size(); for (int i = taskViewCount - 1; i >= 0; i--) { + int taskIndexFromFront = taskViewCount - i - 1; final TaskView tv = taskViews.get(i); Task task = tv.getTask(); boolean currentTaskOccludesLaunchTarget = false; @@ -186,7 +201,7 @@ public class TaskStackAnimationHelper { } else { // Animate the task up if it was occluding the launch target if (currentTaskOccludesLaunchTarget) { - TaskViewAnimation taskAnimation = new TaskViewAnimation( + AnimationProps taskAnimation = new AnimationProps( taskViewEnterFromAffiliatedAppDuration, Interpolators.ALPHA_IN, new AnimatorListenerAdapter() { @Override @@ -202,14 +217,16 @@ public class TaskStackAnimationHelper { } else if (launchState.launchedFromHome) { // Animate the tasks up - int frontIndex = (taskViewCount - i - 1); - int delay = frontIndex * taskViewEnterFromHomeStaggerDelay; - int duration = taskViewEnterFromHomeDuration + - frontIndex * taskViewEnterFromHomeStaggerDelay; - - TaskViewAnimation taskAnimation = new TaskViewAnimation(delay, - duration, Interpolators.DECELERATE_QUINT, - postAnimationTrigger.decrementOnAnimationEnd()); + AnimationProps taskAnimation = new AnimationProps() + .setStartDelay(AnimationProps.ALPHA, taskIndexFromFront * FRAME_OFFSET_MS) + .setDuration(AnimationProps.ALPHA, ENTER_FROM_HOME_ALPHA_DURATION) + .setDuration(AnimationProps.BOUNDS, ENTER_FROM_HOME_TRANSLATION_DURATION - + (taskIndexFromFront * FRAME_OFFSET_MS)) + .setInterpolator(AnimationProps.BOUNDS, + ENTER_FROM_HOME_TRANSLATION_INTERPOLATOR) + .setInterpolator(AnimationProps.ALPHA, + ENTER_FROM_HOME_ALPHA_INTERPOLATOR) + .setListener(postAnimationTrigger.decrementOnAnimationEnd()); postAnimationTrigger.increment(); mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation); } @@ -221,7 +238,6 @@ public class TaskStackAnimationHelper { */ public void startExitToHomeAnimation(boolean animated, ReferenceCountedTrigger postAnimationTrigger) { - Resources res = mStackView.getResources(); TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm(); TaskStackViewScroller stackScroller = mStackView.getScroller(); TaskStack stack = mStackView.getStack(); @@ -232,19 +248,32 @@ public class TaskStackAnimationHelper { } int offscreenY = stackLayout.mStackRect.bottom; - int taskViewExitToHomeDuration = res.getInteger( - R.integer.recents_task_exit_to_home_duration); // Create the animations for each of the tasks List<TaskView> taskViews = mStackView.getTaskViews(); int taskViewCount = taskViews.size(); for (int i = 0; i < taskViewCount; i++) { + int taskIndexFromFront = taskViewCount - i - 1; TaskView tv = taskViews.get(i); Task task = tv.getTask(); - TaskViewAnimation taskAnimation = new TaskViewAnimation( - animated ? taskViewExitToHomeDuration : 0, Interpolators.FAST_OUT_LINEAR_IN, - postAnimationTrigger.decrementOnAnimationEnd()); - postAnimationTrigger.increment(); + + // Animate the tasks down + AnimationProps taskAnimation; + if (animated) { + taskAnimation = new AnimationProps() + .setStartDelay(AnimationProps.ALPHA, i * FRAME_OFFSET_MS) + .setDuration(AnimationProps.ALPHA, EXIT_TO_HOME_ALPHA_DURATION) + .setDuration(AnimationProps.BOUNDS, EXIT_TO_HOME_TRANSLATION_DURATION + + (taskIndexFromFront * FRAME_OFFSET_MS)) + .setInterpolator(AnimationProps.BOUNDS, + EXIT_TO_HOME_TRANSLATION_INTERPOLATOR) + .setInterpolator(AnimationProps.ALPHA, + EXIT_TO_HOME_ALPHA_INTERPOLATOR) + .setListener(postAnimationTrigger.decrementOnAnimationEnd()); + postAnimationTrigger.increment(); + } else { + taskAnimation = AnimationProps.IMMEDIATE; + } stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform, null); @@ -283,7 +312,7 @@ public class TaskStackAnimationHelper { screenPinningRequested, postAnimationTrigger); } else if (currentTaskOccludesLaunchTarget) { // Animate this task out of view - TaskViewAnimation taskAnimation = new TaskViewAnimation( + AnimationProps taskAnimation = new AnimationProps( taskViewExitToAppDuration, Interpolators.ALPHA_OUT, postAnimationTrigger.decrementOnAnimationEnd()); postAnimationTrigger.increment(); @@ -315,7 +344,7 @@ public class TaskStackAnimationHelper { deleteTaskView.setClipViewInStack(false); // Compose the new animation and transform and star the animation - TaskViewAnimation taskAnimation = new TaskViewAnimation(taskViewRemoveAnimDuration, + AnimationProps taskAnimation = new AnimationProps(taskViewRemoveAnimDuration, Interpolators.ALPHA_OUT, new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { @@ -352,7 +381,7 @@ public class TaskStackAnimationHelper { for (int i = taskViewCount - 1; i >= 0; i--) { TaskView tv = taskViews.get(i); Task task = tv.getTask(); - TaskViewAnimation taskAnimation = new TaskViewAnimation(startDelayIncr * i, + AnimationProps taskAnimation = new AnimationProps(startDelayIncr * i, historyTransitionDuration, Interpolators.FAST_OUT_SLOW_IN, postAnimationTrigger.decrementOnAnimationEnd()); postAnimationTrigger.increment(); @@ -381,7 +410,7 @@ public class TaskStackAnimationHelper { int taskViewCount = taskViews.size(); for (int i = taskViewCount - 1; i >= 0; i--) { TaskView tv = taskViews.get(i); - TaskViewAnimation taskAnimation = new TaskViewAnimation(startDelayIncr * i, + AnimationProps taskAnimation = new AnimationProps(startDelayIncr * i, historyTransitionDuration, Interpolators.FAST_OUT_SLOW_IN); stackLayout.getStackTransform(tv.getTask(), stackScroller.getStackScroll(), mTmpTransform, null); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index 232b41648748..1c97b5a22ec7 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -16,6 +16,10 @@ package com.android.systemui.recents.views; +import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; +import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; +import static android.app.ActivityManager.StackId.INVALID_STACK_ID; + import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.ComponentName; @@ -34,9 +38,9 @@ import android.util.MutableBoolean; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; -import android.view.animation.Interpolator; import android.widget.FrameLayout; import com.android.systemui.Interpolators; @@ -85,10 +89,6 @@ import com.android.systemui.recents.model.TaskStack; import java.util.ArrayList; import java.util.List; -import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; -import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; -import static android.app.ActivityManager.StackId.INVALID_STACK_ID; - /* The visual representation of a task stack view */ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCallbacks, @@ -124,7 +124,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal ArrayList<TaskView> mTaskViews = new ArrayList<>(); ArrayList<TaskViewTransform> mCurrentTaskTransforms = new ArrayList<>(); ArraySet<Task.TaskKey> mIgnoreTasks = new ArraySet<>(); - TaskViewAnimation mDeferredTaskViewLayoutAnimation = null; + AnimationProps mDeferredTaskViewLayoutAnimation = null; DozeTrigger mUIDozeTrigger; Task mFocusedTask; @@ -135,6 +135,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal boolean mTaskViewsClipDirty = true; boolean mAwaitingFirstLayout = true; + boolean mInMeasureLayout = false; boolean mEnterAnimationComplete = false; boolean mTouchExplorationEnabled; boolean mScreenPinningEnabled; @@ -537,17 +538,17 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal if (tv == null) { tv = mViewPool.pickUpViewFromPool(task, task); if (task.isFreeformTask()) { - tv.updateViewPropertiesToTaskTransform(transform, TaskViewAnimation.IMMEDIATE, + tv.updateViewPropertiesToTaskTransform(transform, AnimationProps.IMMEDIATE, mRequestUpdateClippingListener); } else { if (Float.compare(transform.p, 0f) <= 0) { tv.updateViewPropertiesToTaskTransform( mLayoutAlgorithm.getBackOfStackTransform(), - TaskViewAnimation.IMMEDIATE, mRequestUpdateClippingListener); + AnimationProps.IMMEDIATE, mRequestUpdateClippingListener); } else { tv.updateViewPropertiesToTaskTransform( mLayoutAlgorithm.getFrontOfStackTransform(), - TaskViewAnimation.IMMEDIATE, mRequestUpdateClippingListener); + AnimationProps.IMMEDIATE, mRequestUpdateClippingListener); } } } else { @@ -580,9 +581,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal * animations that are current running on those task views, and will ensure that the children * {@link TaskView}s will match the set of visible tasks in the stack. * - * @see #relayoutTaskViews(TaskViewAnimation, ArraySet<Task.TaskKey>) + * @see #relayoutTaskViews(AnimationProps, ArraySet<Task.TaskKey>) */ - void relayoutTaskViews(TaskViewAnimation animation) { + void relayoutTaskViews(AnimationProps animation) { relayoutTaskViews(animation, mIgnoreTasks); } @@ -594,7 +595,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal * * @param ignoreTasksSet the set of tasks to ignore in the relayout */ - void relayoutTaskViews(TaskViewAnimation animation, ArraySet<Task.TaskKey> ignoreTasksSet) { + void relayoutTaskViews(AnimationProps animation, ArraySet<Task.TaskKey> ignoreTasksSet) { // If we had a deferred animation, cancel that mDeferredTaskViewLayoutAnimation = null; @@ -623,17 +624,17 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal /** * Posts an update to synchronize the {@link TaskView}s with the stack on the next frame. */ - void relayoutTaskViewsOnNextFrame(TaskViewAnimation animation) { + void relayoutTaskViewsOnNextFrame(AnimationProps animation) { mDeferredTaskViewLayoutAnimation = animation; invalidate(); } /** * Called to update a specific {@link TaskView} to a given {@link TaskViewTransform} with a - * given set of {@link TaskViewAnimation} properties. + * given set of {@link AnimationProps} properties. */ public void updateTaskViewToTransform(TaskView taskView, TaskViewTransform transform, - TaskViewAnimation animation) { + AnimationProps animation) { taskView.updateViewPropertiesToTaskTransform(transform, animation, mRequestUpdateClippingListener); } @@ -1137,6 +1138,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + mInMeasureLayout = true; int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); @@ -1159,22 +1161,29 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal mTmpTaskViews.addAll(mViewPool.getViews()); int taskViewCount = mTmpTaskViews.size(); for (int i = 0; i < taskViewCount; i++) { - TaskView tv = mTmpTaskViews.get(i); - if (tv.getBackground() != null) { - tv.getBackground().getPadding(mTmpRect); - } else { - mTmpRect.setEmpty(); - } - tv.measure( - MeasureSpec.makeMeasureSpec( - mLayoutAlgorithm.mTaskRect.width() + mTmpRect.left + mTmpRect.right, - MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec( - mLayoutAlgorithm.mTaskRect.height() + mTmpRect.top + mTmpRect.bottom, - MeasureSpec.EXACTLY)); + measureTaskView(mTmpTaskViews.get(i)); } setMeasuredDimension(width, height); + mInMeasureLayout = false; + } + + /** + * Measures a TaskView. + */ + private void measureTaskView(TaskView tv) { + if (tv.getBackground() != null) { + tv.getBackground().getPadding(mTmpRect); + } else { + mTmpRect.setEmpty(); + } + tv.measure( + MeasureSpec.makeMeasureSpec( + mLayoutAlgorithm.mTaskRect.width() + mTmpRect.left + mTmpRect.right, + MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec( + mLayoutAlgorithm.mTaskRect.height() + mTmpRect.top + mTmpRect.bottom, + MeasureSpec.EXACTLY)); } /** @@ -1190,15 +1199,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal mTmpTaskViews.addAll(mViewPool.getViews()); int taskViewCount = mTmpTaskViews.size(); for (int i = 0; i < taskViewCount; i++) { - TaskView tv = mTmpTaskViews.get(i); - if (tv.getBackground() != null) { - tv.getBackground().getPadding(mTmpRect); - } else { - mTmpRect.setEmpty(); - } - Rect taskRect = mLayoutAlgorithm.mTaskRect; - tv.layout(taskRect.left - mTmpRect.left, taskRect.top - mTmpRect.top, - taskRect.right + mTmpRect.right, taskRect.bottom + mTmpRect.bottom); + layoutTaskView(mTmpTaskViews.get(i)); } if (changed) { @@ -1207,29 +1208,41 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } } // Relayout all of the task views including the ignored ones - relayoutTaskViews(TaskViewAnimation.IMMEDIATE, EMPTY_TASK_SET); + relayoutTaskViews(AnimationProps.IMMEDIATE, EMPTY_TASK_SET); clipTaskViews(); if (mAwaitingFirstLayout || !mEnterAnimationComplete) { mAwaitingFirstLayout = false; onFirstLayout(); - return; } } + /** + * Lays out a TaskView. + */ + private void layoutTaskView(TaskView tv) { + if (tv.getBackground() != null) { + tv.getBackground().getPadding(mTmpRect); + } else { + mTmpRect.setEmpty(); + } + Rect taskRect = mLayoutAlgorithm.mTaskRect; + tv.layout(taskRect.left - mTmpRect.left, taskRect.top - mTmpRect.top, + taskRect.right + mTmpRect.right, taskRect.bottom + mTmpRect.bottom); + } + /** Handler for the first layout. */ void onFirstLayout() { // Setup the view for the enter animation mAnimationHelper.prepareForEnterAnimation(); // Animate in the freeform workspace - animateFreeformWorkspaceBackgroundAlpha( - mLayoutAlgorithm.getStackState().freeformBackgroundAlpha, 150, - Interpolators.FAST_OUT_SLOW_IN); + int ffBgAlpha = mLayoutAlgorithm.getStackState().freeformBackgroundAlpha; + animateFreeformWorkspaceBackgroundAlpha(ffBgAlpha, new AnimationProps(150, + Interpolators.FAST_OUT_SLOW_IN)); // Set the task focused state without requesting view focus, and leave the focus animations // until after the enter-animation - Task launchTask = mStack.getLaunchTarget(); RecentsConfiguration config = Recents.getConfiguration(); RecentsActivityLaunchState launchState = config.getLaunchState(); int focusedTaskIndex = launchState.getInitialFocusTaskIndex(mStack.getTaskCount()); @@ -1274,7 +1287,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } @Override - protected void dispatchDraw(Canvas canvas) { + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + // Draw the freeform workspace background SystemServicesProxy ssp = Recents.getSystemServices(); if (ssp.hasFreeformWorkspaceSupport()) { @@ -1282,8 +1297,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal mFreeformWorkspaceBackground.draw(canvas); } } - - super.dispatchDraw(canvas); } @Override @@ -1318,7 +1331,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal updateLayoutAlgorithm(true /* boundScroll */); // Animate all the tasks into place - relayoutTaskViews(new TaskViewAnimation(DEFAULT_SYNC_STACK_DURATION, + relayoutTaskViews(new AnimationProps(DEFAULT_SYNC_STACK_DURATION, Interpolators.FAST_OUT_SLOW_IN)); } @@ -1327,7 +1340,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal */ @Override public void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask, - Task newFrontMostTask, TaskViewAnimation animation) { + Task newFrontMostTask, AnimationProps animation) { if (mFocusedTask == removedTask) { resetFocusedTask(removedTask); } @@ -1364,7 +1377,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal @Override public void onHistoryTaskRemoved(TaskStack stack, Task removedTask, - TaskViewAnimation animation) { + AnimationProps animation) { // To be implemented } @@ -1404,7 +1417,21 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal // Add/attach the view to the hierarchy if (isNewView) { - addView(tv, insertIndex); + if (mInMeasureLayout) { + // If we are measuring the layout, then just add the view normally as it will be + // laid out during the layout pass + addView(tv, insertIndex); + } else { + // Otherwise, this is from a bindVisibleTaskViews() call outside the measure/layout + // pass, and we should layout the new child ourselves + ViewGroup.LayoutParams params = tv.getLayoutParams(); + if (params == null) { + params = generateDefaultLayoutParams(); + } + addViewInLayout(tv, insertIndex, params, true /* preventRequestLayout */); + measureTaskView(tv); + layoutTaskView(tv); + } } else { attachViewToParent(tv, insertIndex, tv.getLayoutParams()); } @@ -1463,14 +1490,14 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal public void onFocusStateChanged(float prevFocusState, float curFocusState) { if (mDeferredTaskViewLayoutAnimation == null) { mUIDozeTrigger.poke(); - relayoutTaskViewsOnNextFrame(TaskViewAnimation.IMMEDIATE); + relayoutTaskViewsOnNextFrame(AnimationProps.IMMEDIATE); } } /**** TaskStackViewScroller.TaskStackViewScrollerCallbacks ****/ @Override - public void onScrollChanged(float prevScroll, float curScroll, TaskViewAnimation animation) { + public void onScrollChanged(float prevScroll, float curScroll, AnimationProps animation) { mUIDozeTrigger.poke(); if (animation != null) { relayoutTaskViewsOnNextFrame(animation); @@ -1506,7 +1533,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal tv.dismissTask(); } else { // Otherwise, remove the task from the stack immediately - mStack.removeTask(t, TaskViewAnimation.IMMEDIATE); + mStack.removeTask(t, AnimationProps.IMMEDIATE); } } } @@ -1531,10 +1558,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal mAnimationHelper.startExitToHomeAnimation(event.animated, event.getAnimationTrigger()); // Dismiss the freeform workspace background - int taskViewExitToHomeDuration = getResources().getInteger( - R.integer.recents_task_exit_to_home_duration); - animateFreeformWorkspaceBackgroundAlpha(0, taskViewExitToHomeDuration, - Interpolators.FAST_OUT_SLOW_IN); + int taskViewExitToHomeDuration = TaskStackAnimationHelper.EXIT_TO_HOME_TRANSLATION_DURATION; + animateFreeformWorkspaceBackgroundAlpha(0, new AnimationProps(taskViewExitToHomeDuration, + Interpolators.FAST_OUT_SLOW_IN)); } public final void onBusEvent(DismissFocusedTaskViewEvent event) { @@ -1587,6 +1613,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } public final void onBusEvent(DragStartEvent event) { + // Ensure that the drag task is not animated + addIgnoreTask(event.task); + if (event.task.isFreeformTask()) { // Animate to the front of the stack mStackScroller.animateScroll(mLayoutAlgorithm.mInitialScrollP, null); @@ -1599,7 +1628,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal mTmpTransform.scale = finalScale; mTmpTransform.translationZ = mLayoutAlgorithm.mMaxTranslationZ + 1; updateTaskViewToTransform(event.taskView, mTmpTransform, - new TaskViewAnimation(DRAG_SCALE_DURATION, Interpolators.FAST_OUT_SLOW_IN)); + new AnimationProps(DRAG_SCALE_DURATION, Interpolators.FAST_OUT_SLOW_IN)); } public final void onBusEvent(DragStartInitializeDropTargetsEvent event) { @@ -1611,7 +1640,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } public final void onBusEvent(DragDropTargetChangedEvent event) { - TaskViewAnimation animation = new TaskViewAnimation(250, Interpolators.FAST_OUT_SLOW_IN); + AnimationProps animation = new AnimationProps(250, Interpolators.FAST_OUT_SLOW_IN); if (event.dropTarget instanceof TaskStack.DockState) { // Calculate the new task stack bounds that matches the window size that Recents will // have after the drop @@ -1683,10 +1712,10 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal mLayoutAlgorithm.getStackTransform(event.task, getScroller().getStackScroll(), mTmpTransform, null); event.getAnimationTrigger().increment(); - relayoutTaskViews(new TaskViewAnimation(DEFAULT_SYNC_STACK_DURATION, + relayoutTaskViews(new AnimationProps(DEFAULT_SYNC_STACK_DURATION, Interpolators.FAST_OUT_SLOW_IN)); updateTaskViewToTransform(event.taskView, mTmpTransform, - new TaskViewAnimation(DEFAULT_SYNC_STACK_DURATION, Interpolators.FAST_OUT_SLOW_IN, + new AnimationProps(DEFAULT_SYNC_STACK_DURATION, Interpolators.FAST_OUT_SLOW_IN, event.getAnimationTrigger().decrementOnAnimationEnd())); removeIgnoreTask(event.task); } @@ -1797,15 +1826,15 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal R.string.accessibility_recents_item_dismissed, task.title)); // Remove the task from the stack - mStack.removeTask(task, new TaskViewAnimation(DEFAULT_SYNC_STACK_DURATION, + mStack.removeTask(task, new AnimationProps(DEFAULT_SYNC_STACK_DURATION, Interpolators.FAST_OUT_SLOW_IN)); } /** * Starts an alpha animation on the freeform workspace background. */ - private void animateFreeformWorkspaceBackgroundAlpha(int targetAlpha, int duration, - Interpolator interpolator) { + private void animateFreeformWorkspaceBackgroundAlpha(int targetAlpha, + AnimationProps animation) { if (mFreeformWorkspaceBackground.getAlpha() == targetAlpha) { return; } @@ -1813,8 +1842,12 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal Utilities.cancelAnimationWithoutCallbacks(mFreeformWorkspaceBackgroundAnimator); mFreeformWorkspaceBackgroundAnimator = ObjectAnimator.ofInt(mFreeformWorkspaceBackground, Utilities.DRAWABLE_ALPHA, mFreeformWorkspaceBackground.getAlpha(), targetAlpha); - mFreeformWorkspaceBackgroundAnimator.setDuration(duration); - mFreeformWorkspaceBackgroundAnimator.setInterpolator(interpolator); + mFreeformWorkspaceBackgroundAnimator.setStartDelay( + animation.getDuration(AnimationProps.ALPHA)); + mFreeformWorkspaceBackgroundAnimator.setDuration( + animation.getDuration(AnimationProps.ALPHA)); + mFreeformWorkspaceBackgroundAnimator.setInterpolator( + animation.getInterpolator(AnimationProps.ALPHA)); mFreeformWorkspaceBackgroundAnimator.start(); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java index ced5d4b500f4..c641d75c7bc8 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java @@ -38,7 +38,7 @@ public class TaskStackViewScroller { private static final boolean DEBUG = false; public interface TaskStackViewScrollerCallbacks { - void onScrollChanged(float prevScroll, float curScroll, TaskViewAnimation animation); + void onScrollChanged(float prevScroll, float curScroll, AnimationProps animation); } /** @@ -93,14 +93,14 @@ public class TaskStackViewScroller { * Sets the current stack scroll immediately. */ public void setStackScroll(float s) { - setStackScroll(s, TaskViewAnimation.IMMEDIATE); + setStackScroll(s, AnimationProps.IMMEDIATE); } /** * Sets the current stack scroll, but indicates to the callback the preferred animation to * update to this new scroll. */ - public void setStackScroll(float s, TaskViewAnimation animation) { + public void setStackScroll(float s, AnimationProps animation) { float prevStackScroll = mStackScrollP; mStackScrollP = s; if (mCb != null) { diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java index da99956d2a9c..b8b506800488 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java @@ -546,7 +546,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { mTmpTransform.translationZ = fromTransform.translationZ + (toTransform.translationZ - fromTransform.translationZ) * dismissFraction; - mSv.updateTaskViewToTransform(tv, mTmpTransform, TaskViewAnimation.IMMEDIATE); + mSv.updateTaskViewToTransform(tv, mTmpTransform, AnimationProps.IMMEDIATE); } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index 853f8688767f..703005f00a49 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -29,7 +29,6 @@ import android.graphics.Point; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; -import android.provider.Settings; import android.util.AttributeSet; import android.util.FloatProperty; import android.util.IntProperty; @@ -243,9 +242,9 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks } void updateViewPropertiesToTaskTransform(TaskViewTransform toTransform, - TaskViewAnimation toAnimation, ValueAnimator.AnimatorUpdateListener updateCallback) { + AnimationProps toAnimation, ValueAnimator.AnimatorUpdateListener updateCallback) { RecentsConfiguration config = Recents.getConfiguration(); - Utilities.cancelAnimationWithoutCallbacks(mTransformAnimation); + cancelTransformAnimation(); // Compose the animations for the transform mTmpAnimators.clear(); @@ -255,8 +254,8 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks setTaskProgress(toTransform.p); } // Manually call back to the animator listener and update callback - if (toAnimation.listener != null) { - toAnimation.listener.onAnimationEnd(null); + if (toAnimation.getListener() != null) { + toAnimation.getListener().onAnimationEnd(null); } if (updateCallback != null) { updateCallback.onAnimationUpdate(null); @@ -280,7 +279,7 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks /** Resets this view's properties */ void resetViewProperties() { - Utilities.cancelAnimationWithoutCallbacks(mTransformAnimation); + cancelTransformAnimation(); setDim(0); setVisibility(View.VISIBLE); getViewBounds().reset(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAnimation.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAnimation.java deleted file mode 100644 index 5455042241bc..000000000000 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAnimation.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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.view.animation.Interpolator; - -import com.android.systemui.Interpolators; - -import java.util.List; - -/** - * The animation properties to animate a {@link TaskView} to a given {@link TaskViewTransform}. - */ -public class TaskViewAnimation { - - public static final TaskViewAnimation IMMEDIATE = new TaskViewAnimation(0, - Interpolators.LINEAR); - - public final int startDelay; - public final int duration; - public final Interpolator interpolator; - public final Animator.AnimatorListener listener; - - public TaskViewAnimation(int duration, Interpolator interpolator) { - this(0 /* startDelay */, duration, interpolator, null); - } - - public TaskViewAnimation(int duration, Interpolator interpolator, - Animator.AnimatorListener listener) { - this(0 /* startDelay */, duration, interpolator, listener); - } - - public TaskViewAnimation(int startDelay, int duration, Interpolator interpolator) { - this(startDelay, duration, interpolator, null); - } - - public TaskViewAnimation(int startDelay, int duration, Interpolator interpolator, - Animator.AnimatorListener listener) { - this.startDelay = startDelay; - this.duration = duration; - this.interpolator = interpolator; - this.listener = listener; - } - - /** - * Creates a new {@link AnimatorSet} that will animate the given animators with the current - * animation properties. - */ - public AnimatorSet createAnimator(List<Animator> animators) { - AnimatorSet anim = new AnimatorSet(); - anim.setStartDelay(startDelay); - anim.setDuration(duration); - anim.setInterpolator(interpolator); - if (listener != null) { - anim.addListener(listener); - } - anim.playTogether(animators); - return anim; - } - - /** - * Returns whether this animation has any duration. - */ - public boolean isImmediate() { - return duration <= 0; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java index 7cde46397a81..c91a833e943a 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java @@ -274,8 +274,8 @@ public class TaskViewHeader extends FrameLayout } @Override - protected void dispatchDraw(Canvas canvas) { - super.dispatchDraw(canvas); + public void onDrawForeground(Canvas canvas) { + super.onDrawForeground(canvas); // Draw the dim layer with the rounded corners canvas.drawRoundRect(0, 0, mTaskViewRect.width(), getHeight() + mCornerRadius, diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java index 85b7c82112a4..32878b0afcb7 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java @@ -154,13 +154,13 @@ public class TaskViewTransform { * Applies this transform to a view. */ public void applyToTaskView(TaskView v, ArrayList<Animator> animators, - TaskViewAnimation taskAnimation, boolean allowShadows) { + AnimationProps animation, boolean allowShadows) { // Return early if not visible if (!visible) { return; } - if (taskAnimation.isImmediate()) { + if (animation.isImmediate()) { if (allowShadows && hasTranslationZChangedFrom(v.getTranslationZ())) { v.setTranslationZ(translationZ); } @@ -177,23 +177,27 @@ public class TaskViewTransform { } } else { if (allowShadows && hasTranslationZChangedFrom(v.getTranslationZ())) { - animators.add(ObjectAnimator.ofFloat(v, View.TRANSLATION_Z, v.getTranslationZ(), - translationZ)); + ObjectAnimator anim = ObjectAnimator.ofFloat(v, View.TRANSLATION_Z, + v.getTranslationZ(), translationZ); + animators.add(animation.apply(AnimationProps.TRANSLATION_Z, anim)); } if (hasScaleChangedFrom(v.getScaleX())) { - animators.add(ObjectAnimator.ofPropertyValuesHolder(v, + ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(v, PropertyValuesHolder.ofFloat(View.SCALE_X, v.getScaleX(), scale), - PropertyValuesHolder.ofFloat(View.SCALE_Y, v.getScaleX(), scale))); + PropertyValuesHolder.ofFloat(View.SCALE_Y, v.getScaleX(), scale)); + animators.add(animation.apply(AnimationProps.SCALE, anim)); } if (hasAlphaChangedFrom(v.getAlpha())) { - animators.add(ObjectAnimator.ofFloat(v, View.ALPHA, v.getAlpha(), alpha)); + ObjectAnimator anim = ObjectAnimator.ofFloat(v, View.ALPHA, v.getAlpha(), alpha); + animators.add(animation.apply(AnimationProps.ALPHA, anim)); } if (hasRectChangedFrom(v)) { - animators.add(ObjectAnimator.ofPropertyValuesHolder(v, + ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(v, PropertyValuesHolder.ofInt(LEFT, v.getLeft(), (int) rect.left), PropertyValuesHolder.ofInt(TOP, v.getTop(), (int) rect.top), PropertyValuesHolder.ofInt(RIGHT, v.getRight(), (int) rect.right), - PropertyValuesHolder.ofInt(BOTTOM, v.getBottom(), (int) rect.bottom))); + PropertyValuesHolder.ofInt(BOTTOM, v.getBottom(), (int) rect.bottom)); + animators.add(animation.apply(AnimationProps.BOUNDS, anim)); } } } |