use of com.android.quickstep.util.RemoteAnimationTargetSet in project Neo-Launcher by NeoApplications.
the class TaskViewUtils method getRecentsWindowAnimator.
/**
* @return Animator that controls the window of the opening targets for the recents launch
* animation.
*/
public static ValueAnimator getRecentsWindowAnimator(TaskView v, boolean skipViewChanges, RemoteAnimationTargetCompat[] targets, final ClipAnimationHelper inOutHelper) {
SyncRtSurfaceTransactionApplierCompat applier = new SyncRtSurfaceTransactionApplierCompat(v);
ClipAnimationHelper.TransformParams params = new ClipAnimationHelper.TransformParams().setSyncTransactionApplier(applier);
final RemoteAnimationTargetSet targetSet = new RemoteAnimationTargetSet(targets, MODE_OPENING);
targetSet.addDependentTransactionApplier(applier);
final RecentsView recentsView = v.getRecentsView();
final ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
appAnimator.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
appAnimator.addUpdateListener(new MultiValueUpdateListener() {
// Defer fading out the view until after the app window gets faded in
final FloatProp mViewAlpha = new FloatProp(1f, 0f, 75, 75, LINEAR);
final FloatProp mTaskAlpha = new FloatProp(0f, 1f, 0, 75, LINEAR);
final RectF mThumbnailRect;
{
inOutHelper.setTaskAlphaCallback((t, alpha) -> mTaskAlpha.value);
inOutHelper.prepareAnimation(BaseActivity.fromContext(v.getContext()).getDeviceProfile(), true);
inOutHelper.fromTaskThumbnailView(v.getThumbnail(), (RecentsView) v.getParent(), targetSet.apps.length == 0 ? null : targetSet.apps[0]);
mThumbnailRect = new RectF(inOutHelper.getTargetRect());
mThumbnailRect.offset(-v.getTranslationX(), -v.getTranslationY());
Utilities.scaleRectFAboutCenter(mThumbnailRect, 1 / v.getScaleX());
}
@Override
public void onUpdate(float percent) {
// TODO: Take into account the current fullscreen progress for animating the insets
params.setProgress(1 - percent);
RectF taskBounds = inOutHelper.applyTransform(targetSet, params);
int taskIndex = recentsView.indexOfChild(v);
int centerTaskIndex = recentsView.getCurrentPage();
boolean parallaxCenterAndAdjacentTask = taskIndex != centerTaskIndex;
if (!skipViewChanges && parallaxCenterAndAdjacentTask) {
float scale = taskBounds.width() / mThumbnailRect.width();
v.setScaleX(scale);
v.setScaleY(scale);
v.setTranslationX(taskBounds.centerX() - mThumbnailRect.centerX());
v.setTranslationY(taskBounds.centerY() - mThumbnailRect.centerY());
v.setAlpha(mViewAlpha.value);
}
}
});
appAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
targetSet.release();
}
});
return appAnimator;
}
use of com.android.quickstep.util.RemoteAnimationTargetSet in project Neo-Launcher by NeoApplications.
the class BaseSwipeUpHandler method createWindowAnimationToHome.
/**
* Creates an animation that transforms the current app window into the home app.
* @param startProgress The progress of {@link #mCurrentShift} to start the window from.
* @param homeAnimationFactory The home animation factory.
*/
protected RectFSpringAnim createWindowAnimationToHome(float startProgress, HomeAnimationFactory homeAnimationFactory) {
final RemoteAnimationTargetSet targetSet = mRecentsAnimationWrapper.targetSet;
final RectF startRect = new RectF(mClipAnimationHelper.applyTransform(targetSet, mTransformParams.setProgress(startProgress), false));
final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
final View floatingView = homeAnimationFactory.getFloatingView();
final boolean isFloatingIconView = floatingView instanceof FloatingIconView;
RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mContext.getResources());
if (isFloatingIconView) {
FloatingIconView fiv = (FloatingIconView) floatingView;
anim.addAnimatorListener(fiv);
fiv.setOnTargetChangeListener(anim::onTargetPositionChanged);
}
AnimatorPlaybackController homeAnim = homeAnimationFactory.createActivityAnimationToHome();
// End on a "round-enough" radius so that the shape reveal doesn't have to do too much
// rounding at the end of the animation.
float startRadius = mClipAnimationHelper.getCurrentCornerRadius();
float endRadius = startRect.width() / 6f;
// We want the window alpha to be 0 once this threshold is met, so that the
// FolderIconView can be seen morphing into the icon shape.
final float windowAlphaThreshold = isFloatingIconView ? 1f - SHAPE_PROGRESS_DURATION : 1f;
anim.addOnUpdateListener(new RectFSpringAnim.OnUpdateListener() {
// Alpha interpolates between [1, 0] between progress values [start, end]
final float start = 0f;
final float end = 0.85f;
private float getWindowAlpha(float progress) {
if (progress <= start) {
return 1f;
}
if (progress >= end) {
return 0f;
}
return Utilities.mapToRange(progress, start, end, 1, 0, ACCEL_1_5);
}
@Override
public void onUpdate(RectF currentRect, float progress) {
homeAnim.setPlayFraction(progress);
mTransformParams.setProgress(progress).setCurrentRectAndTargetAlpha(currentRect, getWindowAlpha(progress));
if (isFloatingIconView) {
mTransformParams.setCornerRadius(endRadius * progress + startRadius * (1f - progress));
}
mClipAnimationHelper.applyTransform(targetSet, mTransformParams, false);
if (isFloatingIconView) {
((FloatingIconView) floatingView).update(currentRect, 1f, progress, windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(), false);
}
}
@Override
public void onCancel() {
if (isFloatingIconView) {
((FloatingIconView) floatingView).fastFinish();
}
}
});
anim.addAnimatorListener(new AnimationSuccessListener() {
@Override
public void onAnimationStart(Animator animation) {
homeAnim.dispatchOnStart();
}
@Override
public void onAnimationSuccess(Animator animator) {
homeAnim.getAnimationPlayer().end();
}
});
return anim;
}
use of com.android.quickstep.util.RemoteAnimationTargetSet in project Neo-Launcher by NeoApplications.
the class FallbackActivityControllerHelper method prepareRecentsUI.
@Override
public AnimationFactory prepareRecentsUI(RecentsActivity activity, boolean activityVisible, boolean animateActivity, Consumer<AnimatorPlaybackController> callback) {
if (activityVisible) {
return (transitionLength) -> {
};
}
FallbackRecentsView rv = activity.getOverviewPanel();
rv.setContentAlpha(0);
rv.getClearAllButton().setVisibilityAlpha(0);
rv.setDisallowScrollToClearAll(true);
boolean fromState = !animateActivity;
rv.setInOverviewState(fromState);
return new AnimationFactory() {
boolean isAnimatingToRecents = false;
@Override
public void onRemoteAnimationReceived(RemoteAnimationTargetSet targets) {
isAnimatingToRecents = targets != null && targets.isAnimatingHome();
if (!isAnimatingToRecents) {
rv.setContentAlpha(1);
}
createActivityController(getSwipeUpDestinationAndLength(activity.getDeviceProfile(), activity, new Rect()));
}
@Override
public void createActivityController(long transitionLength) {
AnimatorSet animatorSet = new AnimatorSet();
if (isAnimatingToRecents) {
ObjectAnimator anim = ObjectAnimator.ofFloat(rv, CONTENT_ALPHA, 0, 1);
anim.setDuration(transitionLength).setInterpolator(LINEAR);
animatorSet.play(anim);
}
ObjectAnimator anim = ObjectAnimator.ofFloat(rv, ZOOM_PROGRESS, 1, 0);
anim.setDuration(transitionLength).setInterpolator(LINEAR);
animatorSet.play(anim);
AnimatorPlaybackController controller = AnimatorPlaybackController.wrap(animatorSet, transitionLength);
// Since we are changing the start position of the UI, reapply the state, at the end
controller.setEndAction(() -> {
boolean endState = true;
rv.setInOverviewState(controller.getInterpolatedProgress() > 0.5 ? endState : fromState);
});
callback.accept(controller);
}
};
}
use of com.android.quickstep.util.RemoteAnimationTargetSet in project Neo-Launcher by NeoApplications.
the class QuickstepAppTransitionManagerImpl method getOpeningWindowAnimators.
/**
* @return Animator that controls the window of the opening targets.
*/
private ValueAnimator getOpeningWindowAnimators(View v, RemoteAnimationTargetCompat[] targets, Rect windowTargetBounds, boolean toggleVisibility) {
RectF bounds = new RectF();
FloatingIconView floatingView = FloatingIconView.getFloatingIconView(mLauncher, v, toggleVisibility, bounds, true);
Rect crop = new Rect();
Matrix matrix = new Matrix();
RemoteAnimationTargetSet openingTargets = new RemoteAnimationTargetSet(targets, MODE_OPENING);
SyncRtSurfaceTransactionApplierCompat surfaceApplier = new SyncRtSurfaceTransactionApplierCompat(floatingView);
openingTargets.addDependentTransactionApplier(surfaceApplier);
// Scale the app icon to take up the entire screen. This simplifies the math when
// animating the app window position / scale.
float smallestSize = Math.min(windowTargetBounds.height(), windowTargetBounds.width());
float maxScaleX = smallestSize / bounds.width();
float maxScaleY = smallestSize / bounds.height();
float scale = Math.max(maxScaleX, maxScaleY);
float startScale = 1f;
if (v instanceof BubbleTextView && !(v.getParent() instanceof DeepShortcutView)) {
Drawable dr = ((BubbleTextView) v).getIcon();
if (dr instanceof FastBitmapDrawable) {
startScale = ((FastBitmapDrawable) dr).getAnimatedScale();
}
}
final float initialStartScale = startScale;
int[] dragLayerBounds = new int[2];
mDragLayer.getLocationOnScreen(dragLayerBounds);
// Animate the app icon to the center of the window bounds in screen coordinates.
float centerX = windowTargetBounds.centerX() - dragLayerBounds[0];
float centerY = windowTargetBounds.centerY() - dragLayerBounds[1];
float dX = centerX - bounds.centerX();
float dY = centerY - bounds.centerY();
boolean useUpwardAnimation = bounds.top > centerY || Math.abs(dY) < mLauncher.getDeviceProfile().cellHeightPx;
final long xDuration = useUpwardAnimation ? APP_LAUNCH_CURVED_DURATION : APP_LAUNCH_DOWN_DURATION;
final long yDuration = useUpwardAnimation ? APP_LAUNCH_DURATION : APP_LAUNCH_DOWN_CURVED_DURATION;
final long alphaDuration = useUpwardAnimation ? APP_LAUNCH_ALPHA_DURATION : APP_LAUNCH_ALPHA_DOWN_DURATION;
RectF targetBounds = new RectF(windowTargetBounds);
RectF currentBounds = new RectF();
RectF temp = new RectF();
ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
appAnimator.setDuration(APP_LAUNCH_DURATION);
appAnimator.setInterpolator(LINEAR);
appAnimator.addListener(floatingView);
appAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (v instanceof BubbleTextView) {
((BubbleTextView) v).setStayPressed(false);
}
openingTargets.release();
}
});
float shapeRevealDuration = APP_LAUNCH_DURATION * SHAPE_PROGRESS_DURATION;
final float startCrop;
final float endCrop;
if (mDeviceProfile.isVerticalBarLayout()) {
startCrop = windowTargetBounds.height();
endCrop = windowTargetBounds.width();
} else {
startCrop = windowTargetBounds.width();
endCrop = windowTargetBounds.height();
}
final float initialWindowRadius = supportsRoundedCornersOnWindows(mLauncher.getResources()) ? startCrop / 2f : 0f;
final float windowRadius = mDeviceProfile.isMultiWindowMode ? 0 : getWindowCornerRadius(mLauncher.getResources());
appAnimator.addUpdateListener(new MultiValueUpdateListener() {
FloatProp mDx = new FloatProp(0, dX, 0, xDuration, AGGRESSIVE_EASE);
FloatProp mDy = new FloatProp(0, dY, 0, yDuration, AGGRESSIVE_EASE);
FloatProp mIconScale = new FloatProp(initialStartScale, scale, 0, APP_LAUNCH_DURATION, EXAGGERATED_EASE);
FloatProp mIconAlpha = new FloatProp(1f, 0f, APP_LAUNCH_ALPHA_START_DELAY, alphaDuration, LINEAR);
FloatProp mCroppedSize = new FloatProp(startCrop, endCrop, 0, CROP_DURATION, EXAGGERATED_EASE);
FloatProp mWindowRadius = new FloatProp(initialWindowRadius, windowRadius, 0, RADIUS_DURATION, EXAGGERATED_EASE);
@Override
public void onUpdate(float percent) {
// Calculate app icon size.
float iconWidth = bounds.width() * mIconScale.value;
float iconHeight = bounds.height() * mIconScale.value;
// Animate the window crop so that it starts off as a square.
final int windowWidth;
final int windowHeight;
if (mDeviceProfile.isVerticalBarLayout()) {
windowWidth = (int) mCroppedSize.value;
windowHeight = windowTargetBounds.height();
} else {
windowWidth = windowTargetBounds.width();
windowHeight = (int) mCroppedSize.value;
}
crop.set(0, 0, windowWidth, windowHeight);
// Scale the app window to match the icon size.
float scaleX = iconWidth / windowWidth;
float scaleY = iconHeight / windowHeight;
float scale = Math.min(1f, Math.max(scaleX, scaleY));
float scaledWindowWidth = windowWidth * scale;
float scaledWindowHeight = windowHeight * scale;
float offsetX = (scaledWindowWidth - iconWidth) / 2;
float offsetY = (scaledWindowHeight - iconHeight) / 2;
// Calculate the window position
temp.set(bounds);
temp.offset(dragLayerBounds[0], dragLayerBounds[1]);
temp.offset(mDx.value, mDy.value);
Utilities.scaleRectFAboutCenter(temp, mIconScale.value);
float transX0 = temp.left - offsetX;
float transY0 = temp.top - offsetY;
float croppedHeight = (windowTargetBounds.height() - crop.height()) * scale;
float croppedWidth = (windowTargetBounds.width() - crop.width()) * scale;
SurfaceParams[] params = new SurfaceParams[targets.length];
for (int i = targets.length - 1; i >= 0; i--) {
RemoteAnimationTargetCompat target = targets[i];
Rect targetCrop;
final float alpha;
final float cornerRadius;
if (target.mode == MODE_OPENING) {
matrix.setScale(scale, scale);
matrix.postTranslate(transX0, transY0);
targetCrop = crop;
alpha = 1f - mIconAlpha.value;
cornerRadius = mWindowRadius.value;
matrix.mapRect(currentBounds, targetBounds);
if (mDeviceProfile.isVerticalBarLayout()) {
currentBounds.right -= croppedWidth;
} else {
currentBounds.bottom -= croppedHeight;
}
floatingView.update(currentBounds, mIconAlpha.value, percent, 0f, cornerRadius * scale, true);
} else {
matrix.setTranslate(target.position.x, target.position.y);
targetCrop = target.sourceContainerBounds;
alpha = 1f;
cornerRadius = 0;
}
params[i] = new SurfaceParams(target.leash, alpha, matrix, targetCrop, RemoteAnimationProvider.getLayer(target, MODE_OPENING), cornerRadius);
}
surfaceApplier.scheduleApply(params);
}
});
return appAnimator;
}
use of com.android.quickstep.util.RemoteAnimationTargetSet in project Neo-Launcher by NeoApplications.
the class AppToOverviewAnimationProvider method createWindowAnimation.
/**
* Create remote window animation from the currently running app to the overview panel.
*
* @param targetCompats the target apps
* @return animation from app to overview
*/
@Override
public AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] targetCompats) {
if (mRecentsView != null) {
mRecentsView.setRunningTaskIconScaledDown(true);
}
AnimatorSet anim = new AnimatorSet();
anim.addListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
mHelper.onSwipeUpToRecentsComplete(mActivity);
if (mRecentsView != null) {
mRecentsView.animateUpRunningTaskIconScale();
}
}
});
if (mActivity == null) {
Log.e(TAG, "Animation created, before activity");
anim.play(ValueAnimator.ofInt(0, 1).setDuration(RECENTS_LAUNCH_DURATION));
return anim;
}
RemoteAnimationTargetSet targetSet = new RemoteAnimationTargetSet(targetCompats, MODE_CLOSING);
// Use the top closing app to determine the insets for the animation
RemoteAnimationTargetCompat runningTaskTarget = targetSet.findTask(mTargetTaskId);
if (runningTaskTarget == null) {
Log.e(TAG, "No closing app");
anim.play(ValueAnimator.ofInt(0, 1).setDuration(RECENTS_LAUNCH_DURATION));
return anim;
}
final ClipAnimationHelper clipHelper = new ClipAnimationHelper(mActivity);
// At this point, the activity is already started and laid-out. Get the home-bounds
// relative to the screen using the rootView of the activity.
int[] loc = new int[2];
View rootView = mActivity.getRootView();
rootView.getLocationOnScreen(loc);
Rect homeBounds = new Rect(loc[0], loc[1], loc[0] + rootView.getWidth(), loc[1] + rootView.getHeight());
clipHelper.updateSource(homeBounds, runningTaskTarget);
Rect targetRect = new Rect();
mHelper.getSwipeUpDestinationAndLength(mActivity.getDeviceProfile(), mActivity, targetRect);
clipHelper.updateTargetRect(targetRect);
clipHelper.prepareAnimation(mActivity.getDeviceProfile(), false);
ClipAnimationHelper.TransformParams params = new ClipAnimationHelper.TransformParams().setSyncTransactionApplier(new SyncRtSurfaceTransactionApplierCompat(rootView));
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.setDuration(RECENTS_LAUNCH_DURATION);
valueAnimator.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
valueAnimator.addUpdateListener((v) -> {
params.setProgress((float) v.getAnimatedValue());
clipHelper.applyTransform(targetSet, params);
});
if (targetSet.isAnimatingHome()) {
// If we are animating home, fade in the opening targets
RemoteAnimationTargetSet openingSet = new RemoteAnimationTargetSet(targetCompats, MODE_OPENING);
TransactionCompat transaction = new TransactionCompat();
valueAnimator.addUpdateListener((v) -> {
for (RemoteAnimationTargetCompat app : openingSet.apps) {
transaction.setAlpha(app.leash, (float) v.getAnimatedValue());
}
transaction.apply();
});
}
anim.play(valueAnimator);
return anim;
}
Aggregations