use of com.android.launcher3.tapl.Overview in project android_packages_apps_Launcher3 by crdroidandroid.
the class QuickstepTransitionManager method getLauncherContentAnimator.
/**
* Content is everything on screen except the background and the floating view (if any).
*
* @param isAppOpening True when this is called when an app is opening.
* False when this is called when an app is closing.
* @param startDelay Start delay duration.
*/
private Pair<AnimatorSet, Runnable> getLauncherContentAnimator(boolean isAppOpening, int startDelay) {
AnimatorSet launcherAnimator = new AnimatorSet();
Runnable endListener;
float[] alphas = isAppOpening ? new float[] { 1, 0 } : new float[] { 0, 1 };
float[] scales = isAppOpening ? new float[] { 1, mContentScale } : new float[] { mContentScale, 1 };
if (mLauncher.isInState(ALL_APPS)) {
// All Apps in portrait mode is full screen, so we only animate AllAppsContainerView.
final View appsView = mLauncher.getAppsView();
final float startAlpha = appsView.getAlpha();
final float startScale = SCALE_PROPERTY.get(appsView);
appsView.setAlpha(alphas[0]);
SCALE_PROPERTY.set(appsView, scales[0]);
ObjectAnimator alpha = ObjectAnimator.ofFloat(appsView, View.ALPHA, alphas);
alpha.setDuration(CONTENT_ALPHA_DURATION);
alpha.setInterpolator(LINEAR);
appsView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
alpha.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
appsView.setLayerType(View.LAYER_TYPE_NONE, null);
}
});
ObjectAnimator scale = ObjectAnimator.ofFloat(appsView, SCALE_PROPERTY, scales);
scale.setInterpolator(AGGRESSIVE_EASE);
scale.setDuration(CONTENT_SCALE_DURATION);
launcherAnimator.play(alpha);
launcherAnimator.play(scale);
endListener = () -> {
appsView.setAlpha(startAlpha);
SCALE_PROPERTY.set(appsView, startScale);
appsView.setLayerType(View.LAYER_TYPE_NONE, null);
};
} else if (mLauncher.isInState(OVERVIEW)) {
endListener = composeViewContentAnimator(launcherAnimator, alphas, scales);
} else {
List<View> viewsToAnimate = new ArrayList<>();
Workspace workspace = mLauncher.getWorkspace();
workspace.forEachVisiblePage(view -> viewsToAnimate.add(((CellLayout) view).getShortcutsAndWidgets()));
viewsToAnimate.add(mLauncher.getHotseat());
viewsToAnimate.forEach(view -> {
view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator scaleAnim = ObjectAnimator.ofFloat(view, SCALE_PROPERTY, scales).setDuration(CONTENT_SCALE_DURATION);
scaleAnim.setInterpolator(DEACCEL_1_5);
launcherAnimator.play(scaleAnim);
});
final boolean scrimEnabled = ENABLE_SCRIM_FOR_APP_LAUNCH.get();
if (scrimEnabled) {
int scrimColor = Themes.getAttrColor(mLauncher, R.attr.overviewScrimColor);
int scrimColorTrans = ColorUtils.setAlphaComponent(scrimColor, 0);
int[] colors = isAppOpening ? new int[] { scrimColorTrans, scrimColor } : new int[] { scrimColor, scrimColorTrans };
ScrimView scrimView = mLauncher.getScrimView();
if (scrimView.getBackground() instanceof ColorDrawable) {
scrimView.setBackgroundColor(colors[0]);
ObjectAnimator scrim = ObjectAnimator.ofArgb(scrimView, VIEW_BACKGROUND_COLOR, colors);
scrim.setDuration(CONTENT_SCRIM_DURATION);
scrim.setInterpolator(DEACCEL_1_5);
launcherAnimator.play(scrim);
}
}
// Pause page indicator animations as they lead to layer trashing.
mLauncher.getWorkspace().getPageIndicator().pauseAnimations();
endListener = () -> {
viewsToAnimate.forEach(view -> {
SCALE_PROPERTY.set(view, 1f);
view.setLayerType(View.LAYER_TYPE_NONE, null);
});
if (scrimEnabled) {
mLauncher.getScrimView().setBackgroundColor(Color.TRANSPARENT);
}
mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();
};
}
launcherAnimator.setStartDelay(startDelay);
return new Pair<>(launcherAnimator, endListener);
}
use of com.android.launcher3.tapl.Overview in project android_packages_apps_Launcher3 by crdroidandroid.
the class QuickstepTransitionManager method getBackgroundAnimator.
private ObjectAnimator getBackgroundAnimator(RemoteAnimationTargetCompat[] appTargets) {
// When launching an app from overview that doesn't map to a task, we still want to just
// blur the wallpaper instead of the launcher surface as well
boolean allowBlurringLauncher = mLauncher.getStateManager().getState() != OVERVIEW;
DepthController depthController = mLauncher.getDepthController();
ObjectAnimator backgroundRadiusAnim = ObjectAnimator.ofFloat(depthController, DEPTH, BACKGROUND_APP.getDepth(mLauncher)).setDuration(APP_LAUNCH_DURATION);
if (allowBlurringLauncher) {
final SurfaceControl dimLayer;
if (BlurUtils.supportsBlursOnWindows()) {
// Create a temporary effect layer, that lives on top of launcher, so we can apply
// the blur to it. The EffectLayer will be fullscreen, which will help with caching
// optimizations on the SurfaceFlinger side:
// - Results would be able to be cached as a texture
// - There won't be texture allocation overhead, because EffectLayers don't have
// buffers
ViewRootImpl viewRootImpl = mLauncher.getDragLayer().getViewRootImpl();
SurfaceControl parent = viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null;
dimLayer = new SurfaceControl.Builder().setName("Blur layer").setParent(parent).setOpaque(false).setHidden(false).setEffectLayer().build();
} else {
dimLayer = null;
}
depthController.setSurface(dimLayer);
backgroundRadiusAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
depthController.setIsInLaunchTransition(true);
}
@Override
public void onAnimationEnd(Animator animation) {
depthController.setIsInLaunchTransition(false);
depthController.setSurface(null);
if (dimLayer != null) {
new SurfaceControl.Transaction().remove(dimLayer).apply();
}
}
});
}
return backgroundRadiusAnim;
}
use of com.android.launcher3.tapl.Overview in project android_packages_apps_Launcher3 by crdroidandroid.
the class NoButtonNavbarToOverviewTouchController method goToOverviewOrHomeOnDragEnd.
private void goToOverviewOrHomeOnDragEnd(float velocity) {
boolean goToHomeInsteadOfOverview = !mMotionPauseDetector.isPaused();
if (goToHomeInsteadOfOverview) {
new OverviewToHomeAnim(mLauncher, () -> onSwipeInteractionCompleted(NORMAL)).animateWithVelocity(velocity);
}
if (mReachedOverview) {
float distanceDp = dpiFromPx(Math.max(Math.abs(mRecentsView.getTranslationX()), Math.abs(mRecentsView.getTranslationY())));
long duration = (long) Math.max(TRANSLATION_ANIM_MIN_DURATION_MS, distanceDp / TRANSLATION_ANIM_VELOCITY_DP_PER_MS);
mRecentsView.animate().translationX(0).translationY(0).setInterpolator(ACCEL_DEACCEL).setDuration(duration).withEndAction(goToHomeInsteadOfOverview ? null : this::maybeSwipeInteractionToOverviewComplete);
if (!goToHomeInsteadOfOverview) {
// Return to normal properties for the overview state.
StateAnimationConfig config = new StateAnimationConfig();
config.duration = duration;
LauncherState state = mLauncher.getStateManager().getState();
mLauncher.getStateManager().createAtomicAnimation(state, state, config).start();
}
}
}
use of com.android.launcher3.tapl.Overview in project android_packages_apps_Launcher3 by crdroidandroid.
the class NoButtonQuickSwitchTouchController method onDragEnd.
@Override
public void onDragEnd(PointF velocity) {
boolean horizontalFling = mSwipeDetector.isFling(velocity.x);
boolean verticalFling = mSwipeDetector.isFling(velocity.y);
boolean noFling = !horizontalFling && !verticalFling;
if (mMotionPauseDetector.isPaused() && noFling) {
cancelAnimations();
StateAnimationConfig config = new StateAnimationConfig();
config.duration = ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW;
Animator overviewAnim = mLauncher.getStateManager().createAtomicAnimation(mStartState, OVERVIEW, config);
overviewAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
onAnimationToStateCompleted(OVERVIEW);
}
});
overviewAnim.start();
return;
}
final LauncherState targetState;
if (horizontalFling && verticalFling) {
if (velocity.x < 0) {
// Flinging left and up or down both go back home.
targetState = NORMAL;
} else {
if (velocity.y > 0) {
// Flinging right and down goes to quick switch.
targetState = QUICK_SWITCH;
} else {
// Flinging up and right could go either home or to quick switch.
// Determine the target based on the higher velocity.
targetState = Math.abs(velocity.x) > Math.abs(velocity.y) ? QUICK_SWITCH : NORMAL;
}
}
} else if (horizontalFling) {
targetState = velocity.x > 0 ? QUICK_SWITCH : NORMAL;
} else if (verticalFling) {
targetState = velocity.y > 0 ? QUICK_SWITCH : NORMAL;
} else {
// If user isn't flinging, just snap to the closest state.
boolean passedHorizontalThreshold = mXOverviewAnim.getInterpolatedProgress() > 0.5f;
boolean passedVerticalThreshold = mYOverviewAnim.value > 1f;
targetState = passedHorizontalThreshold && !passedVerticalThreshold ? QUICK_SWITCH : NORMAL;
}
// Animate the various components to the target state.
float xProgress = mXOverviewAnim.getProgressFraction();
float startXProgress = Utilities.boundToRange(xProgress + velocity.x * getSingleFrameMs(mLauncher) / mXRange, 0f, 1f);
final float endXProgress = targetState == NORMAL ? 0 : 1;
long xDuration = BaseSwipeDetector.calculateDuration(velocity.x, Math.abs(endXProgress - startXProgress));
ValueAnimator xOverviewAnim = mXOverviewAnim.getAnimationPlayer();
xOverviewAnim.setFloatValues(startXProgress, endXProgress);
xOverviewAnim.setDuration(xDuration).setInterpolator(scrollInterpolatorForVelocity(velocity.x));
mXOverviewAnim.dispatchOnStart();
boolean flingUpToNormal = verticalFling && velocity.y < 0 && targetState == NORMAL;
float yProgress = mYOverviewAnim.value;
float startYProgress = Utilities.boundToRange(yProgress - velocity.y * getSingleFrameMs(mLauncher) / mYRange, 0f, mMaxYProgress);
final float endYProgress;
if (flingUpToNormal) {
endYProgress = 1;
} else if (targetState == NORMAL) {
// Keep overview at its current scale/translationY as it slides off the screen.
endYProgress = startYProgress;
} else {
endYProgress = 0;
}
float yDistanceToCover = Math.abs(endYProgress - startYProgress) * mYRange;
long yDuration = (long) (yDistanceToCover / Math.max(1f, Math.abs(velocity.y)));
ValueAnimator yOverviewAnim = mYOverviewAnim.animateToValue(startYProgress, endYProgress);
yOverviewAnim.setDuration(yDuration);
mYOverviewAnim.updateValue(startYProgress);
ValueAnimator nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
if (flingUpToNormal && !mIsHomeScreenVisible) {
// We are flinging to home while workspace is invisible, run the same staggered
// animation as from an app.
StateAnimationConfig config = new StateAnimationConfig();
// Update mNonOverviewAnim to do nothing so it doesn't interfere.
config.animFlags = SKIP_ALL_ANIMATIONS;
updateNonOverviewAnim(targetState, config);
nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
new WorkspaceRevealAnim(mLauncher, false).start();
} else {
boolean canceled = targetState == NORMAL;
if (canceled) {
// Let the state manager know that the animation didn't go to the target state,
// but don't clean up yet (we already clean up when the animation completes).
mNonOverviewAnim.getTarget().removeListener(mClearStateOnCancelListener);
mNonOverviewAnim.dispatchOnCancel();
}
float startProgress = mNonOverviewAnim.getProgressFraction();
float endProgress = canceled ? 0 : 1;
nonOverviewAnim.setFloatValues(startProgress, endProgress);
mNonOverviewAnim.dispatchOnStart();
}
nonOverviewAnim.setDuration(Math.max(xDuration, yDuration));
mNonOverviewAnim.setEndAction(() -> onAnimationToStateCompleted(targetState));
cancelAnimations();
xOverviewAnim.start();
yOverviewAnim.start();
nonOverviewAnim.start();
}
use of com.android.launcher3.tapl.Overview in project android_packages_apps_Launcher3 by crdroidandroid.
the class PortraitStatesTouchController method initCurrentAnimation.
@Override
protected float initCurrentAnimation() {
float range = getShiftRange();
long maxAccuracy = (long) (2 * range);
float startVerticalShift = mFromState.getVerticalProgress(mLauncher) * range;
float endVerticalShift = mToState.getVerticalProgress(mLauncher) * range;
float totalShift = endVerticalShift - startVerticalShift;
final StateAnimationConfig config = totalShift == 0 ? new StateAnimationConfig() : getConfigForStates(mFromState, mToState);
config.duration = maxAccuracy;
if (mCurrentAnimation != null) {
mCurrentAnimation.getTarget().removeListener(mClearStateOnCancelListener);
mCurrentAnimation.dispatchOnCancel();
}
mGoingBetweenStates = true;
if (mFromState == OVERVIEW && mToState == NORMAL && mOverviewPortraitStateTouchHelper.shouldSwipeDownReturnToApp()) {
// Reset the state manager, when changing the interaction mode
mLauncher.getStateManager().goToState(OVERVIEW, false);
mGoingBetweenStates = false;
mCurrentAnimation = mOverviewPortraitStateTouchHelper.createSwipeDownToTaskAppAnimation(maxAccuracy, Interpolators.LINEAR).createPlaybackController();
mLauncher.getStateManager().setCurrentUserControlledAnimation(mCurrentAnimation);
RecentsView recentsView = mLauncher.getOverviewPanel();
totalShift = LayoutUtils.getShelfTrackingDistance(mLauncher, mLauncher.getDeviceProfile(), recentsView.getPagedOrientationHandler());
} else {
mCurrentAnimation = mLauncher.getStateManager().createAnimationToNewWorkspace(mToState, config);
}
mCurrentAnimation.getTarget().addListener(mClearStateOnCancelListener);
if (totalShift == 0) {
totalShift = Math.signum(mFromState.ordinal - mToState.ordinal) * OverviewState.getDefaultSwipeHeight(mLauncher);
}
return 1 / totalShift;
}
Aggregations