blob: 7ae6cb7661adc132c9c5965811c288088519f838 [file] [log] [blame]
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.quickstep.util;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_DEPTH_CONTROLLER;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_SCRIM;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.view.View;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Workspace;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.util.DynamicResource;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.plugins.ResourceProvider;
/**
* Creates an animation that reveals the workspace.
* This is used in conjunction with the swipe up to home animation.
*/
public class WorkspaceRevealAnim {
// Should be used for animations running alongside this WorkspaceRevealAnim.
public static final int DURATION_MS = 350;
private final float mScaleStart;
private final AnimatorSet mAnimators = new AnimatorSet();
public WorkspaceRevealAnim(Launcher launcher, boolean animateOverviewScrim) {
prepareToAnimate(launcher, animateOverviewScrim);
ResourceProvider rp = DynamicResource.provider(launcher);
mScaleStart = rp.getFloat(R.dimen.swipe_up_scale_start);
Workspace workspace = launcher.getWorkspace();
workspace.setPivotToScaleWithSelf(launcher.getHotseat());
// Add reveal animations.
addRevealAnimatorsForView(workspace);
addRevealAnimatorsForView(launcher.getHotseat());
// Add overview scrim animation.
if (animateOverviewScrim) {
PendingAnimation overviewScrimBuilder = new PendingAnimation(DURATION_MS);
launcher.getWorkspace().getStateTransitionAnimation()
.setScrim(overviewScrimBuilder, NORMAL, new StateAnimationConfig());
mAnimators.play(overviewScrimBuilder.buildAnim());
}
// Add depth controller animation.
if (launcher instanceof BaseQuickstepLauncher) {
PendingAnimation depthBuilder = new PendingAnimation(DURATION_MS);
DepthController depth = ((BaseQuickstepLauncher) launcher).getDepthController();
depth.setStateWithAnimation(NORMAL, new StateAnimationConfig(), depthBuilder);
mAnimators.play(depthBuilder.buildAnim());
}
// Add sysui scrim animation.
mAnimators.play(launcher.getRootView().getSysUiScrim().createSysuiMultiplierAnim(0f, 1f));
mAnimators.setDuration(DURATION_MS);
mAnimators.setInterpolator(Interpolators.DECELERATED_EASE);
}
private void addRevealAnimatorsForView(View v) {
ObjectAnimator scale = ObjectAnimator.ofFloat(v, SCALE_PROPERTY, mScaleStart, 1f);
scale.setDuration(DURATION_MS);
scale.setInterpolator(Interpolators.DECELERATED_EASE);
mAnimators.play(scale);
ObjectAnimator alpha = ObjectAnimator.ofFloat(v, View.ALPHA, 0, 1f);
alpha.setDuration(DURATION_MS);
alpha.setInterpolator(Interpolators.DECELERATED_EASE);
mAnimators.play(alpha);
mAnimators.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
SCALE_PROPERTY.set(v, 1f);
v.setAlpha(1f);
}
});
}
/**
* Setup workspace with 0 duration.
*/
private void prepareToAnimate(Launcher launcher, boolean animateOverviewScrim) {
StateAnimationConfig config = new StateAnimationConfig();
config.animFlags = SKIP_OVERVIEW | SKIP_DEPTH_CONTROLLER | SKIP_SCRIM;
config.duration = 0;
// setRecentsAttachedToAppWindow() will animate recents out.
launcher.getStateManager().createAtomicAnimation(BACKGROUND_APP, NORMAL, config).start();
// Stop scrolling so that it doesn't interfere with the translation offscreen.
launcher.<RecentsView>getOverviewPanel().forceFinishScroller();
if (animateOverviewScrim) {
launcher.getWorkspace().getStateTransitionAnimation()
.setScrim(NO_ANIM_PROPERTY_SETTER, BACKGROUND_APP, config);
}
}
public AnimatorSet getAnimators() {
return mAnimators;
}
public WorkspaceRevealAnim addAnimatorListener(Animator.AnimatorListener listener) {
mAnimators.addListener(listener);
return this;
}
/**
* Starts the animation.
*/
public void start() {
mAnimators.start();
}
}