1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.launcher3.uioverrides; 17 18 import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; 19 import static com.android.launcher3.LauncherState.FAST_OVERVIEW; 20 import static com.android.launcher3.LauncherState.OVERVIEW; 21 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_FADE; 22 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_SCALE; 23 import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE_IN_OUT; 24 import static com.android.launcher3.anim.Interpolators.LINEAR; 25 import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_START_INTERPOLATOR; 26 import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_TRANSLATION_Y_FACTOR; 27 import static com.android.quickstep.views.LauncherRecentsView.TRANSLATION_Y_FACTOR; 28 import static com.android.quickstep.views.RecentsViewContainer.CONTENT_ALPHA; 29 30 import android.animation.ValueAnimator; 31 import android.annotation.TargetApi; 32 import android.os.Build; 33 import android.view.animation.Interpolator; 34 35 import com.android.launcher3.Launcher; 36 import com.android.launcher3.LauncherState; 37 import com.android.launcher3.LauncherStateManager.AnimationConfig; 38 import com.android.launcher3.LauncherStateManager.StateHandler; 39 import com.android.launcher3.anim.AnimatorSetBuilder; 40 import com.android.launcher3.anim.Interpolators; 41 import com.android.launcher3.anim.PropertySetter; 42 import com.android.quickstep.views.LauncherRecentsView; 43 import com.android.quickstep.views.RecentsViewContainer; 44 45 @TargetApi(Build.VERSION_CODES.O) 46 public class RecentsViewStateController implements StateHandler { 47 48 private final Launcher mLauncher; 49 private final LauncherRecentsView mRecentsView; 50 private final RecentsViewContainer mRecentsViewContainer; 51 RecentsViewStateController(Launcher launcher)52 public RecentsViewStateController(Launcher launcher) { 53 mLauncher = launcher; 54 mRecentsView = launcher.getOverviewPanel(); 55 mRecentsViewContainer = launcher.getOverviewPanelContainer(); 56 } 57 58 @Override setState(LauncherState state)59 public void setState(LauncherState state) { 60 mRecentsViewContainer.setContentAlpha(state.overviewUi ? 1 : 0); 61 float[] scaleTranslationYFactor = state.getOverviewScaleAndTranslationYFactor(mLauncher); 62 SCALE_PROPERTY.set(mRecentsView, scaleTranslationYFactor[0]); 63 mRecentsView.setTranslationYFactor(scaleTranslationYFactor[1]); 64 if (state.overviewUi) { 65 mRecentsView.updateEmptyMessage(); 66 mRecentsView.resetTaskVisuals(); 67 } 68 } 69 70 @Override setStateWithAnimation(final LauncherState toState, AnimatorSetBuilder builder, AnimationConfig config)71 public void setStateWithAnimation(final LauncherState toState, 72 AnimatorSetBuilder builder, AnimationConfig config) { 73 if (!config.playAtomicComponent()) { 74 // The entire recents animation is played atomically. 75 return; 76 } 77 PropertySetter setter = config.getPropertySetter(builder); 78 float[] scaleTranslationYFactor = toState.getOverviewScaleAndTranslationYFactor(mLauncher); 79 Interpolator scaleAndTransYInterpolator = builder.getInterpolator( 80 ANIM_OVERVIEW_SCALE, LINEAR); 81 if (mLauncher.getStateManager().getState() == OVERVIEW && toState == FAST_OVERVIEW) { 82 scaleAndTransYInterpolator = Interpolators.clampToProgress( 83 QUICK_SCRUB_START_INTERPOLATOR, 0, QUICK_SCRUB_TRANSLATION_Y_FACTOR); 84 } 85 setter.setFloat(mRecentsView, SCALE_PROPERTY, scaleTranslationYFactor[0], 86 scaleAndTransYInterpolator); 87 setter.setFloat(mRecentsView, TRANSLATION_Y_FACTOR, scaleTranslationYFactor[1], 88 scaleAndTransYInterpolator); 89 setter.setFloat(mRecentsViewContainer, CONTENT_ALPHA, toState.overviewUi ? 1 : 0, 90 builder.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT)); 91 92 if (!toState.overviewUi) { 93 builder.addOnFinishRunnable(mRecentsView::resetTaskVisuals); 94 } 95 96 if (toState.overviewUi) { 97 ValueAnimator updateAnim = ValueAnimator.ofFloat(0, 1); 98 updateAnim.addUpdateListener(valueAnimator -> { 99 // While animating into recents, update the visible task data as needed 100 mRecentsView.loadVisibleTaskData(); 101 }); 102 updateAnim.setDuration(config.duration); 103 builder.play(updateAnim); 104 mRecentsView.updateEmptyMessage(); 105 } 106 } 107 } 108