mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-03 17:36:49 +00:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user