1 /* 2 * Copyright (C) 2015 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 17 package com.android.launcher3; 18 19 import static com.android.launcher3.LauncherAnimUtils.DRAWABLE_ALPHA; 20 import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; 21 import static com.android.launcher3.LauncherState.HOTSEAT_ICONS; 22 import static com.android.launcher3.LauncherState.HOTSEAT_SEARCH_BOX; 23 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_FADE; 24 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_SCALE; 25 import static com.android.launcher3.anim.Interpolators.LINEAR; 26 import static com.android.launcher3.anim.Interpolators.ZOOM_OUT; 27 import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER; 28 import static com.android.launcher3.graphics.WorkspaceAndHotseatScrim.SCRIM_PROGRESS; 29 import static com.android.launcher3.graphics.WorkspaceAndHotseatScrim.SYSUI_PROGRESS; 30 31 import android.view.View; 32 import android.view.animation.Interpolator; 33 34 import com.android.launcher3.LauncherState.PageAlphaProvider; 35 import com.android.launcher3.LauncherStateManager.AnimationConfig; 36 import com.android.launcher3.anim.AnimatorSetBuilder; 37 import com.android.launcher3.anim.PropertySetter; 38 import com.android.launcher3.graphics.WorkspaceAndHotseatScrim; 39 40 /** 41 * Manages the animations between each of the workspace states. 42 */ 43 public class WorkspaceStateTransitionAnimation { 44 45 private final Launcher mLauncher; 46 private final Workspace mWorkspace; 47 48 private float mNewScale; 49 50 public WorkspaceStateTransitionAnimation(Launcher launcher, Workspace workspace) { 51 mLauncher = launcher; 52 mWorkspace = workspace; 53 } 54 55 public void setState(LauncherState toState) { 56 setWorkspaceProperty(toState, NO_ANIM_PROPERTY_SETTER, new AnimatorSetBuilder(), 57 new AnimationConfig()); 58 } 59 60 public void setStateWithAnimation(LauncherState toState, AnimatorSetBuilder builder, 61 AnimationConfig config) { 62 setWorkspaceProperty(toState, config.getPropertySetter(builder), builder, config); 63 } 64 65 public float getFinalScale() { 66 return mNewScale; 67 } 68 69 /** 70 * Starts a transition animation for the workspace. 71 */ 72 private void setWorkspaceProperty(LauncherState state, PropertySetter propertySetter, 73 AnimatorSetBuilder builder, AnimationConfig config) { 74 float[] scaleAndTranslation = state.getWorkspaceScaleAndTranslation(mLauncher); 75 mNewScale = scaleAndTranslation[0]; 76 PageAlphaProvider pageAlphaProvider = state.getWorkspacePageAlphaProvider(mLauncher); 77 final int childCount = mWorkspace.getChildCount(); 78 for (int i = 0; i < childCount; i++) { 79 applyChildState(state, (CellLayout) mWorkspace.getChildAt(i), i, pageAlphaProvider, 80 propertySetter, builder, config); 81 } 82 83 int elements = state.getVisibleElements(mLauncher); 84 Interpolator fadeInterpolator = builder.getInterpolator(ANIM_WORKSPACE_FADE, 85 pageAlphaProvider.interpolator); 86 boolean playAtomicComponent = config.playAtomicComponent(); 87 if (playAtomicComponent) { 88 Interpolator scaleInterpolator = builder.getInterpolator(ANIM_WORKSPACE_SCALE, ZOOM_OUT); 89 propertySetter.setFloat(mWorkspace, SCALE_PROPERTY, mNewScale, scaleInterpolator); 90 float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0; 91 propertySetter.setViewAlpha(mLauncher.getHotseat().getLayout(), hotseatIconsAlpha, 92 fadeInterpolator); 93 propertySetter.setViewAlpha(mLauncher.getWorkspace().getPageIndicator(), 94 hotseatIconsAlpha, fadeInterpolator); 95 } 96 97 if (!config.playNonAtomicComponent()) { 98 // Only the alpha and scale, handled above, are included in the atomic animation. 99 return; 100 } 101 102 Interpolator translationInterpolator = !playAtomicComponent ? LINEAR : ZOOM_OUT; 103 propertySetter.setFloat(mWorkspace, View.TRANSLATION_X, 104 scaleAndTranslation[1], translationInterpolator); 105 propertySetter.setFloat(mWorkspace, View.TRANSLATION_Y, 106 scaleAndTranslation[2], translationInterpolator); 107 108 propertySetter.setViewAlpha(mLauncher.getHotseatSearchBox(), 109 (elements & HOTSEAT_SEARCH_BOX) != 0 ? 1 : 0, fadeInterpolator); 110 111 // Set scrim 112 WorkspaceAndHotseatScrim scrim = mLauncher.getDragLayer().getScrim(); 113 propertySetter.setFloat(scrim, SCRIM_PROGRESS, state.getWorkspaceScrimAlpha(mLauncher), 114 LINEAR); 115 propertySetter.setFloat(scrim, SYSUI_PROGRESS, state.hasSysUiScrim ? 1 : 0, LINEAR); 116 } 117 118 public void applyChildState(LauncherState state, CellLayout cl, int childIndex) { 119 applyChildState(state, cl, childIndex, state.getWorkspacePageAlphaProvider(mLauncher), 120 NO_ANIM_PROPERTY_SETTER, new AnimatorSetBuilder(), new AnimationConfig()); 121 } 122 123 private void applyChildState(LauncherState state, CellLayout cl, int childIndex, 124 PageAlphaProvider pageAlphaProvider, PropertySetter propertySetter, 125 AnimatorSetBuilder builder, AnimationConfig config) { 126 float pageAlpha = pageAlphaProvider.getPageAlpha(childIndex); 127 int drawableAlpha = Math.round(pageAlpha * (state.hasWorkspacePageBackground ? 255 : 0)); 128 129 if (config.playNonAtomicComponent()) { 130 propertySetter.setInt(cl.getScrimBackground(), 131 DRAWABLE_ALPHA, drawableAlpha, ZOOM_OUT); 132 } 133 if (config.playAtomicComponent()) { 134 Interpolator fadeInterpolator = builder.getInterpolator(ANIM_WORKSPACE_FADE, 135 pageAlphaProvider.interpolator); 136 propertySetter.setFloat(cl.getShortcutsAndWidgets(), View.ALPHA, 137 pageAlpha, fadeInterpolator); 138 } 139 } 140 }