Animating task icon scale when using long swipe

> Separating the task icon animation and setter into 2 separate methods and calling each appropriately
> Using taskId instead of TaskView for ignoreSet as taskView can be reassigned

Bug: 110893730
Change-Id: I7bc958e53becffdf633766373b257ead2eeef2ad
This commit is contained in:
Sunny Goyal
2018-07-10 11:37:14 -07:00
parent 070d23091a
commit d7e217abb3
8 changed files with 105 additions and 78 deletions

View File

@@ -134,7 +134,7 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
/**
* Must return a non-null controller is supportsLongSwipe was true.
*/
LongSwipeHelper getLongSwipeController(T activity, RemoteAnimationTargetSet targetSet);
LongSwipeHelper getLongSwipeController(T activity, int runningTaskId);
/**
* Used for containerType in {@link com.android.launcher3.logging.UserEventDispatcher}
@@ -384,12 +384,11 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
}
@Override
public LongSwipeHelper getLongSwipeController(Launcher activity,
RemoteAnimationTargetSet targetSet) {
public LongSwipeHelper getLongSwipeController(Launcher activity, int runningTaskId) {
if (activity.getDeviceProfile().isVerticalBarLayout()) {
return null;
}
return new LongSwipeHelper(activity, targetSet);
return new LongSwipeHelper(activity, runningTaskId);
}
@Override
@@ -571,8 +570,7 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
}
@Override
public LongSwipeHelper getLongSwipeController(RecentsActivity activity,
RemoteAnimationTargetSet targetSet) {
public LongSwipeHelper getLongSwipeController(RecentsActivity activity, int runningTaskId) {
return null;
}

View File

@@ -26,7 +26,6 @@ import android.animation.ValueAnimator;
import android.view.animation.Interpolator;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.LauncherStateManager;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
@@ -41,7 +40,6 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.util.FlingBlockCheck;
import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -56,15 +54,15 @@ public class LongSwipeHelper {
Math.min(1 / MIN_PROGRESS_TO_ALL_APPS, 1 / (1 - MIN_PROGRESS_TO_ALL_APPS));
private final Launcher mLauncher;
private final RemoteAnimationTargetSet mTargetSet;
private final int mRunningTaskId;
private float mMaxSwipeDistance = 1;
private AnimatorPlaybackController mAnimator;
private FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck();
LongSwipeHelper(Launcher launcher, RemoteAnimationTargetSet targetSet) {
LongSwipeHelper(Launcher launcher, int runningTaskId) {
mLauncher = launcher;
mTargetSet = targetSet;
mRunningTaskId = runningTaskId;
init();
}
@@ -151,10 +149,16 @@ public class LongSwipeHelper {
}
private void onSwipeAnimationComplete(boolean toAllApps, boolean isFling, Runnable callback) {
RecentsView rv = mLauncher.getOverviewPanel();
if (!toAllApps) {
rv.setIgnoreResetTask(mRunningTaskId);
}
mLauncher.getStateManager().goToState(toAllApps ? ALL_APPS : OVERVIEW, false);
if (!toAllApps) {
DiscoveryBounce.showForOverviewIfNeeded(mLauncher);
mLauncher.<RecentsView>getOverviewPanel().setSwipeDownShouldLaunchApp(true);
rv.animateUpRunningTaskIconScale();
rv.setSwipeDownShouldLaunchApp(true);
}
mLauncher.getUserEventDispatcher().logStateChangeAction(

View File

@@ -285,7 +285,7 @@ public class OverviewCommandHelper {
}
mActivity = activity;
mRecentsView = mActivity.getOverviewPanel();
mRecentsView.setRunningTaskIconScaledDown(true /* isScaledDown */, false /* animate */);
mRecentsView.setRunningTaskIconScaledDown(true);
if (!mUserEventLogged) {
activity.getUserEventDispatcher().logActionCommand(Action.Command.RECENTS_BUTTON,
mHelper.getContainerType(), ContainerType.TASKSWITCHER);
@@ -308,8 +308,7 @@ public class OverviewCommandHelper {
@Override
public void onAnimationSuccess(Animator animator) {
if (mRecentsView != null) {
mRecentsView.setRunningTaskIconScaledDown(false /* isScaledDown */,
true /* animate */);
mRecentsView.animateUpRunningTaskIconScale();
}
}
});

View File

@@ -133,7 +133,7 @@ public class TaskSystemShortcut<T extends SystemShortcut> extends SystemShortcut
public void onLayoutChange(View v, int l, int t, int r, int b,
int oldL, int oldT, int oldR, int oldB) {
taskView.getRootView().removeOnLayoutChangeListener(this);
recentsView.removeIgnoreResetTask(taskView);
recentsView.clearIgnoreResetTask(taskId);
// Start animating in the side pages once launcher has been resized
recentsView.dismissTask(taskView, false, false);
@@ -178,7 +178,7 @@ public class TaskSystemShortcut<T extends SystemShortcut> extends SystemShortcut
// Hide the task view and wait for the window to be resized
// TODO: Consider animating in launcher and do an in-place start activity
// afterwards
recentsView.addIgnoreResetTask(taskView);
recentsView.setIgnoreResetTask(taskId);
taskView.setAlpha(0f);
};

View File

@@ -436,7 +436,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
mRecentsView.showTask(mRunningTaskId);
mRecentsView.setRunningTaskHidden(true);
mRecentsView.setRunningTaskIconScaledDown(true /* isScaledDown */, false /* animate */);
mRecentsView.setRunningTaskIconScaledDown(true);
mLayoutListener.open();
mStateCallback.setState(STATE_LAUNCHER_STARTED);
}
@@ -841,7 +841,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
mActivityControlHelper.getAlphaProperty(mActivity).setValue(1);
mRecentsView.setRunningTaskHidden(false);
mRecentsView.setRunningTaskIconScaledDown(false /* isScaledDown */, false /* animate */);
mRecentsView.setRunningTaskIconScaledDown(false);
mQuickScrubController.cancelActiveQuickscrub();
}
@@ -907,7 +907,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
mActivityControlHelper.onSwipeUpComplete(mActivity);
// Animate the first icon.
mRecentsView.setRunningTaskIconScaledDown(false /* isScaledDown */, true /* animate */);
mRecentsView.animateUpRunningTaskIconScale();
mRecentsView.setSwipeDownShouldLaunchApp(true);
RecentsModel.getInstance(mContext).onOverviewShown(false, TAG);
@@ -939,7 +939,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
}
mQuickScrubController.onFinishedTransitionToQuickScrub();
mRecentsView.setRunningTaskIconScaledDown(false /* isScaledDown */, true /* animate */);
mRecentsView.animateUpRunningTaskIconScale();
RecentsModel.getInstance(mContext).onOverviewShown(false, TAG);
}
@@ -1044,7 +1044,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
}
mLongSwipeController = mActivityControlHelper.getLongSwipeController(
mActivity, mRecentsAnimationWrapper.targetSet);
mActivity, mRunningTaskId);
onLongSwipeDisplacementUpdated();
setTargetAlphaProvider(mLongSwipeController::getTargetAlpha);
}

View File

@@ -48,7 +48,6 @@ import android.support.annotation.Nullable;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.SparseBooleanArray;
@@ -249,8 +248,8 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
@ViewDebug.ExportedProperty(category = "launcher")
private float mContentAlpha = 1;
// Keeps track of task views whose visual state should not be reset
private ArraySet<TaskView> mIgnoreResetTaskViews = new ArraySet<>();
// Keeps track of task id whose visual state should not be reset
private int mIgnoreResetTaskId = -1;
// Variables for empty state
private final Drawable mEmptyIcon;
@@ -457,18 +456,19 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
// Unload existing visible task data
unloadVisibleTaskData();
TaskView ignoreRestTaskView =
mIgnoreResetTaskId == -1 ? null : getTaskView(mIgnoreResetTaskId);
final int requiredTaskCount = tasks.size();
if (getTaskViewCount() != requiredTaskCount) {
if (oldChildCount > 0) {
removeView(mClearAllButton);
}
for (int i = getChildCount(); i < requiredTaskCount; i++) {
final TaskView taskView = (TaskView) inflater.inflate(R.layout.task, this, false);
addView(taskView, 0);
addView(inflater.inflate(R.layout.task, this, false));
}
while (getChildCount() > requiredTaskCount) {
final TaskView taskView = (TaskView) getChildAt(getChildCount() - 1);
removeView(taskView);
removeView(getChildAt(getChildCount() - 1));
}
if (requiredTaskCount > 0) {
addView(mClearAllButton);
@@ -482,6 +482,12 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
final TaskView taskView = (TaskView) getChildAt(pageIndex);
taskView.bind(task);
}
if (mIgnoreResetTaskId != -1 && getTaskView(mIgnoreResetTaskId) != ignoreRestTaskView) {
// If the taskView mapping is changing, do not preserve the visuals. Since we are
// mostly preserving the first task, and new taskViews are added to the end, it should
// generally map to the same task.
mIgnoreResetTaskId = -1;
}
resetTaskVisuals();
if (oldChildCount != getChildCount()) {
@@ -501,14 +507,18 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
public void resetTaskVisuals() {
for (int i = getTaskViewCount() - 1; i >= 0; i--) {
TaskView taskView = (TaskView) getChildAt(i);
if (!mIgnoreResetTaskViews.contains(taskView)) {
if (mIgnoreResetTaskId != taskView.getTask().key.id) {
taskView.resetVisualProperties();
}
}
if (mRunningTaskTileHidden) {
setRunningTaskHidden(mRunningTaskTileHidden);
}
applyIconScale(false /* animate */);
// Force apply the scale.
if (mIgnoreResetTaskId != mRunningTaskId) {
applyRunningTaskIconScale();
}
updateCurveProperties();
// Update the set of visible task's data
@@ -660,6 +670,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
public void reset() {
mRunningTaskId = -1;
mRunningTaskTileHidden = false;
mIgnoreResetTaskId = -1;
unloadVisibleTaskData();
setCurrentPage(0);
@@ -721,10 +732,10 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
boolean runningTaskTileHidden = mRunningTaskTileHidden;
boolean runningTaskIconScaledDown = mRunningTaskIconScaledDown;
setRunningTaskIconScaledDown(false, false);
setRunningTaskIconScaledDown(false);
setRunningTaskHidden(false);
mRunningTaskId = runningTaskId;
setRunningTaskIconScaledDown(runningTaskIconScaledDown, false);
setRunningTaskIconScaledDown(runningTaskIconScaledDown);
setRunningTaskHidden(runningTaskTileHidden);
setCurrentPage(0);
@@ -754,23 +765,25 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
return mQuickScrubController;
}
public void setRunningTaskIconScaledDown(boolean isScaledDown, boolean animate) {
if (mRunningTaskIconScaledDown == isScaledDown) {
return;
public void setRunningTaskIconScaledDown(boolean isScaledDown) {
if (mRunningTaskIconScaledDown != isScaledDown) {
mRunningTaskIconScaledDown = isScaledDown;
applyRunningTaskIconScale();
}
mRunningTaskIconScaledDown = isScaledDown;
applyIconScale(animate);
}
private void applyIconScale(boolean animate) {
float scale = mRunningTaskIconScaledDown ? 0 : 1;
private void applyRunningTaskIconScale() {
TaskView firstTask = getTaskView(mRunningTaskId);
if (firstTask != null) {
if (animate) {
firstTask.animateIconToScaleAndDim(scale);
} else {
firstTask.setIconScaleAndDim(scale);
}
firstTask.setIconScaleAndDim(mRunningTaskIconScaledDown ? 0 : 1);
}
}
public void animateUpRunningTaskIconScale() {
mRunningTaskIconScaledDown = false;
TaskView firstTask = getTaskView(mRunningTaskId);
if (firstTask != null) {
firstTask.animateIconScaleAndDimIntoView();
}
}
@@ -836,12 +849,14 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
public float scrollFromEdge;
}
public void addIgnoreResetTask(TaskView taskView) {
mIgnoreResetTaskViews.add(taskView);
public void setIgnoreResetTask(int taskId) {
mIgnoreResetTaskId = taskId;
}
public void removeIgnoreResetTask(TaskView taskView) {
mIgnoreResetTaskViews.remove(taskView);
public void clearIgnoreResetTask(int taskId) {
if (mIgnoreResetTaskId == taskId) {
mIgnoreResetTaskId = -1;
}
}
private void addDismissedTaskAnimations(View taskView, AnimatorSet anim, long duration) {

View File

@@ -54,19 +54,6 @@ public class TaskThumbnailView extends View {
private static final LightingColorFilter[] sDimFilterCache = new LightingColorFilter[256];
private static final LightingColorFilter[] sHighlightFilterCache = new LightingColorFilter[256];
public static final Property<TaskThumbnailView, Float> DIM_ALPHA_MULTIPLIER =
new FloatProperty<TaskThumbnailView>("dimAlphaMultiplier") {
@Override
public void setValue(TaskThumbnailView thumbnail, float dimAlphaMultiplier) {
thumbnail.setDimAlphaMultipler(dimAlphaMultiplier);
}
@Override
public Float get(TaskThumbnailView thumbnailView) {
return thumbnailView.mDimAlphaMultiplier;
}
};
public static final Property<TaskThumbnailView, Float> DIM_ALPHA =
new FloatProperty<TaskThumbnailView>("dimAlpha") {
@Override

View File

@@ -18,7 +18,8 @@ package com.android.quickstep.views;
import static android.widget.Toast.LENGTH_SHORT;
import static com.android.quickstep.views.TaskThumbnailView.DIM_ALPHA_MULTIPLIER;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -43,6 +44,7 @@ import android.widget.Toast;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.quickstep.TaskSystemShortcut;
@@ -94,12 +96,27 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback
}
};
private static FloatProperty<TaskView> FOCUS_TRANSITION =
new FloatProperty<TaskView>("focusTransition") {
@Override
public void setValue(TaskView taskView, float v) {
taskView.setIconAndDimTransitionProgress(v);
}
@Override
public Float get(TaskView taskView) {
return taskView.mFocusTransitionProgress;
}
};
private Task mTask;
private TaskThumbnailView mSnapshotView;
private IconView mIconView;
private float mCurveScale;
private float mZoomScale;
private Animator mDimAlphaAnim;
private Animator mIconAndDimAnimator;
private float mFocusTransitionProgress = 1;
public TaskView(Context context) {
this(context, null);
@@ -201,28 +218,35 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback
// Do nothing
}
public void animateIconToScaleAndDim(float scale) {
mIconView.animate().scaleX(scale).scaleY(scale).setDuration(SCALE_ICON_DURATION).start();
mDimAlphaAnim = ObjectAnimator.ofFloat(mSnapshotView, DIM_ALPHA_MULTIPLIER, 1 - scale,
scale);
mDimAlphaAnim.setDuration(DIM_ANIM_DURATION);
mDimAlphaAnim.addListener(new AnimatorListenerAdapter() {
private void setIconAndDimTransitionProgress(float progress) {
mFocusTransitionProgress = progress;
mSnapshotView.setDimAlphaMultipler(progress);
float scale = FAST_OUT_SLOW_IN.getInterpolation(Utilities.boundToRange(
progress * DIM_ANIM_DURATION / SCALE_ICON_DURATION, 0, 1));
mIconView.setScaleX(scale);
mIconView.setScaleY(scale);
}
public void animateIconScaleAndDimIntoView() {
if (mIconAndDimAnimator != null) {
mIconAndDimAnimator.cancel();
}
mIconAndDimAnimator = ObjectAnimator.ofFloat(this, FOCUS_TRANSITION, 1);
mIconAndDimAnimator.setDuration(DIM_ANIM_DURATION).setInterpolator(LINEAR);
mIconAndDimAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mDimAlphaAnim = null;
mIconAndDimAnimator = null;
}
});
mDimAlphaAnim.start();
mIconAndDimAnimator.start();
}
protected void setIconScaleAndDim(float iconScale) {
mIconView.animate().cancel();
mIconView.setScaleX(iconScale);
mIconView.setScaleY(iconScale);
if (mDimAlphaAnim != null) {
mDimAlphaAnim.cancel();
if (mIconAndDimAnimator != null) {
mIconAndDimAnimator.cancel();
}
mSnapshotView.setDimAlphaMultipler(iconScale);
setIconAndDimTransitionProgress(iconScale);
}
public void resetVisualProperties() {