Refine long-press enter and exit animations
am: 545c5c2
* commit '545c5c20d3b1f424b2f1917a262a5e8130dab6d0':
Refine long-press enter and exit animations
Change-Id: I229da9faaee36f491ee40ad00fea9273919e71a9
This commit is contained in:
@@ -19,6 +19,7 @@ package com.android.systemui.recents.views;
|
|||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -77,7 +78,7 @@ public class TaskStackAnimationHelper {
|
|||||||
|
|
||||||
public static final int ENTER_FROM_HOME_ALPHA_DURATION = 100;
|
public static final int ENTER_FROM_HOME_ALPHA_DURATION = 100;
|
||||||
public static final int ENTER_FROM_HOME_TRANSLATION_DURATION = 333;
|
public static final int ENTER_FROM_HOME_TRANSLATION_DURATION = 333;
|
||||||
public static final int ENTER_WHILE_DOCKING_DURATION = 150;
|
public static final int ENTER_WHILE_DOCKING_DURATION = 250;
|
||||||
|
|
||||||
private static final PathInterpolator ENTER_FROM_HOME_TRANSLATION_INTERPOLATOR =
|
private static final PathInterpolator ENTER_FROM_HOME_TRANSLATION_INTERPOLATOR =
|
||||||
new PathInterpolator(0, 0, 0, 1f);
|
new PathInterpolator(0, 0, 0, 1f);
|
||||||
@@ -135,6 +136,8 @@ public class TaskStackAnimationHelper {
|
|||||||
R.dimen.recents_task_stack_animation_affiliate_enter_offset);
|
R.dimen.recents_task_stack_animation_affiliate_enter_offset);
|
||||||
int launchedWhileDockingOffset = res.getDimensionPixelSize(
|
int launchedWhileDockingOffset = res.getDimensionPixelSize(
|
||||||
R.dimen.recents_task_stack_animation_launched_while_docking_offset);
|
R.dimen.recents_task_stack_animation_launched_while_docking_offset);
|
||||||
|
boolean isLandscape = mStackView.getContext().getApplicationContext().getResources()
|
||||||
|
.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
|
||||||
|
|
||||||
// Prepare each of the task views for their enter animation from front to back
|
// Prepare each of the task views for their enter animation from front to back
|
||||||
List<TaskView> taskViews = mStackView.getTaskViews();
|
List<TaskView> taskViews = mStackView.getTaskViews();
|
||||||
@@ -169,7 +172,10 @@ public class TaskStackAnimationHelper {
|
|||||||
mTmpTransform.alpha = 0f;
|
mTmpTransform.alpha = 0f;
|
||||||
mStackView.updateTaskViewToTransform(tv, mTmpTransform, AnimationProps.IMMEDIATE);
|
mStackView.updateTaskViewToTransform(tv, mTmpTransform, AnimationProps.IMMEDIATE);
|
||||||
} else if (launchState.launchedViaDockGesture) {
|
} else if (launchState.launchedViaDockGesture) {
|
||||||
mTmpTransform.rect.offset(0, launchedWhileDockingOffset);
|
int offset = isLandscape
|
||||||
|
? launchedWhileDockingOffset
|
||||||
|
: (int) (offscreenYOffset * 0.9f);
|
||||||
|
mTmpTransform.rect.offset(0, offset);
|
||||||
mTmpTransform.alpha = 0f;
|
mTmpTransform.alpha = 0f;
|
||||||
mStackView.updateTaskViewToTransform(tv, mTmpTransform, AnimationProps.IMMEDIATE);
|
mStackView.updateTaskViewToTransform(tv, mTmpTransform, AnimationProps.IMMEDIATE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -332,13 +332,18 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
|||||||
|
|
||||||
public void stopDragging(int position, SnapTarget target, long duration,
|
public void stopDragging(int position, SnapTarget target, long duration,
|
||||||
Interpolator interpolator) {
|
Interpolator interpolator) {
|
||||||
stopDragging(position, target, duration, 0 /* startDelay*/, interpolator);
|
stopDragging(position, target, duration, 0 /* startDelay*/, 0 /* endDelay */, interpolator);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopDragging(int position, SnapTarget target, long duration,
|
||||||
|
Interpolator interpolator, long endDelay) {
|
||||||
|
stopDragging(position, target, duration, 0 /* startDelay*/, endDelay, interpolator);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopDragging(int position, SnapTarget target, long duration, long startDelay,
|
public void stopDragging(int position, SnapTarget target, long duration, long startDelay,
|
||||||
Interpolator interpolator) {
|
long endDelay, Interpolator interpolator) {
|
||||||
mHandle.setTouching(false, true /* animate */);
|
mHandle.setTouching(false, true /* animate */);
|
||||||
flingTo(position, target, duration, startDelay, interpolator);
|
flingTo(position, target, duration, startDelay, endDelay, interpolator);
|
||||||
mWindowManager.setSlippery(true);
|
mWindowManager.setSlippery(true);
|
||||||
releaseBackground();
|
releaseBackground();
|
||||||
}
|
}
|
||||||
@@ -471,21 +476,22 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
|||||||
if (logMetrics) {
|
if (logMetrics) {
|
||||||
logResizeEvent(snapTarget);
|
logResizeEvent(snapTarget);
|
||||||
}
|
}
|
||||||
ValueAnimator anim = getFlingAnimator(position, snapTarget);
|
ValueAnimator anim = getFlingAnimator(position, snapTarget, 0 /* endDelay */);
|
||||||
mFlingAnimationUtils.apply(anim, position, snapTarget.position, velocity);
|
mFlingAnimationUtils.apply(anim, position, snapTarget.position, velocity);
|
||||||
anim.start();
|
anim.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void flingTo(int position, SnapTarget target, long duration, long startDelay,
|
private void flingTo(int position, SnapTarget target, long duration, long startDelay,
|
||||||
Interpolator interpolator) {
|
long endDelay, Interpolator interpolator) {
|
||||||
ValueAnimator anim = getFlingAnimator(position, target);
|
ValueAnimator anim = getFlingAnimator(position, target, endDelay);
|
||||||
anim.setDuration(duration);
|
anim.setDuration(duration);
|
||||||
anim.setStartDelay(startDelay);
|
anim.setStartDelay(startDelay);
|
||||||
anim.setInterpolator(interpolator);
|
anim.setInterpolator(interpolator);
|
||||||
anim.start();
|
anim.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ValueAnimator getFlingAnimator(int position, final SnapTarget snapTarget) {
|
private ValueAnimator getFlingAnimator(int position, final SnapTarget snapTarget,
|
||||||
|
final long endDelay) {
|
||||||
ValueAnimator anim = ValueAnimator.ofInt(position, snapTarget.position);
|
ValueAnimator anim = ValueAnimator.ofInt(position, snapTarget.position);
|
||||||
anim.addUpdateListener(new AnimatorUpdateListener() {
|
anim.addUpdateListener(new AnimatorUpdateListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -496,16 +502,31 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
|||||||
: snapTarget.position, snapTarget);
|
: snapTarget.position, snapTarget);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Runnable endAction = () -> {
|
||||||
|
commitSnapFlags(snapTarget);
|
||||||
|
mWindowManagerProxy.setResizing(false);
|
||||||
|
mDockSide = WindowManager.DOCKED_INVALID;
|
||||||
|
mCurrentAnimator = null;
|
||||||
|
mEntranceAnimationRunning = false;
|
||||||
|
mExitAnimationRunning = false;
|
||||||
|
EventBus.getDefault().send(new StoppedDragingEvent());
|
||||||
|
};
|
||||||
anim.addListener(new AnimatorListenerAdapter() {
|
anim.addListener(new AnimatorListenerAdapter() {
|
||||||
|
|
||||||
|
private boolean mCancelled;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationCancel(Animator animation) {
|
||||||
|
mCancelled = true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationEnd(Animator animation) {
|
public void onAnimationEnd(Animator animation) {
|
||||||
commitSnapFlags(snapTarget);
|
if (endDelay == 0 || mCancelled) {
|
||||||
mWindowManagerProxy.setResizing(false);
|
endAction.run();
|
||||||
mDockSide = WindowManager.DOCKED_INVALID;
|
} else {
|
||||||
mCurrentAnimator = null;
|
postDelayed(endAction, endDelay);
|
||||||
mEntranceAnimationRunning = false;
|
}
|
||||||
mExitAnimationRunning = false;
|
|
||||||
EventBus.getDefault().send(new StoppedDragingEvent());
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mCurrentAnimator = anim;
|
mCurrentAnimator = anim;
|
||||||
@@ -733,8 +754,10 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
|||||||
mDockSide, mDockedTaskRect);
|
mDockSide, mDockedTaskRect);
|
||||||
calculateBoundsForPosition(mExitStartPosition,
|
calculateBoundsForPosition(mExitStartPosition,
|
||||||
DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect);
|
DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect);
|
||||||
|
mOtherInsetRect.set(mOtherTaskRect);
|
||||||
|
applyExitAnimationParallax(mOtherTaskRect, position);
|
||||||
mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, null,
|
mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, null,
|
||||||
mOtherTaskRect, null);
|
mOtherTaskRect, mOtherInsetRect);
|
||||||
} else if (taskPosition != TASK_POSITION_SAME) {
|
} else if (taskPosition != TASK_POSITION_SAME) {
|
||||||
calculateBoundsForPosition(position, DockedDividerUtils.invertDockSide(mDockSide),
|
calculateBoundsForPosition(position, DockedDividerUtils.invertDockSide(mDockSide),
|
||||||
mOtherRect);
|
mOtherRect);
|
||||||
@@ -773,6 +796,16 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
|||||||
dimFraction);
|
dimFraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyExitAnimationParallax(Rect taskRect, int position) {
|
||||||
|
if (mDockSide == WindowManager.DOCKED_TOP) {
|
||||||
|
taskRect.offset(0, (int) ((position - mExitStartPosition) * 0.25f));
|
||||||
|
} else if (mDockSide == WindowManager.DOCKED_LEFT) {
|
||||||
|
taskRect.offset((int) ((position - mExitStartPosition) * 0.25f), 0);
|
||||||
|
} else if (mDockSide == WindowManager.DOCKED_RIGHT) {
|
||||||
|
taskRect.offset((int) ((mExitStartPosition - position) * 0.25f), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private float getDimFraction(int position, SnapTarget dismissTarget) {
|
private float getDimFraction(int position, SnapTarget dismissTarget) {
|
||||||
if (mEntranceAnimationRunning) {
|
if (mEntranceAnimationRunning) {
|
||||||
return 0f;
|
return 0f;
|
||||||
@@ -956,14 +989,17 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
|||||||
if (mAnimateAfterRecentsDrawn) {
|
if (mAnimateAfterRecentsDrawn) {
|
||||||
mAnimateAfterRecentsDrawn = false;
|
mAnimateAfterRecentsDrawn = false;
|
||||||
updateDockSide();
|
updateDockSide();
|
||||||
stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), 250,
|
|
||||||
Interpolators.TOUCH_RESPONSE);
|
// Delay switching resizing mode because this might cause jank in recents animation
|
||||||
|
// that's long than this animation.
|
||||||
|
stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(),
|
||||||
|
250 /* startDelay */, Interpolators.FAST_OUT_SLOW_IN, 200 /* endDelay */);
|
||||||
}
|
}
|
||||||
if (mGrowAfterRecentsDrawn) {
|
if (mGrowAfterRecentsDrawn) {
|
||||||
mGrowAfterRecentsDrawn = false;
|
mGrowAfterRecentsDrawn = false;
|
||||||
updateDockSide();
|
updateDockSide();
|
||||||
stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), 250,
|
stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), 250,
|
||||||
Interpolators.TOUCH_RESPONSE);
|
Interpolators.FAST_OUT_SLOW_IN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -979,7 +1015,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
|||||||
mExitAnimationRunning = true;
|
mExitAnimationRunning = true;
|
||||||
mExitStartPosition = getCurrentPosition();
|
mExitStartPosition = getCurrentPosition();
|
||||||
stopDragging(mExitStartPosition, target, 336 /* duration */, 100 /* startDelay */,
|
stopDragging(mExitStartPosition, target, 336 /* duration */, 100 /* startDelay */,
|
||||||
Interpolators.TOUCH_RESPONSE);
|
0 /* endDelay */, Interpolators.FAST_OUT_SLOW_IN);
|
||||||
|
|
||||||
// Vibrate after undocking
|
// Vibrate after undocking
|
||||||
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
|
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
|
||||||
|
|||||||
Reference in New Issue
Block a user