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.anim.AnimatorSetBuilder.ANIM_HOTSEAT_SCALE; 23 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_HOTSEAT_TRANSLATE; 24 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_FADE; 25 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_SCALE; 26 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_TRANSLATE; 27 import static com.android.launcher3.anim.Interpolators.LINEAR; 28 import static com.android.launcher3.anim.Interpolators.ZOOM_OUT; 29 import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER; 30 import static com.android.launcher3.graphics.WorkspaceAndHotseatScrim.SCRIM_PROGRESS; 31 import static com.android.launcher3.graphics.WorkspaceAndHotseatScrim.SYSUI_PROGRESS; 32 33 import android.view.View; 34 import android.view.animation.Interpolator; 35 36 import com.android.launcher3.LauncherState.PageAlphaProvider; 37 import com.android.launcher3.LauncherState.ScaleAndTranslation; 38 import com.android.launcher3.LauncherStateManager.AnimationConfig; 39 import com.android.launcher3.anim.AnimatorSetBuilder; 40 import com.android.launcher3.anim.PropertySetter; 41 import com.android.launcher3.graphics.WorkspaceAndHotseatScrim; 42 43 /** 44 * Manages the animations between each of the workspace states. 45 */ 46 public class WorkspaceStateTransitionAnimation { 47 48 private final Launcher mLauncher; 49 private final Workspace mWorkspace; 50 51 private float mNewScale; 52 WorkspaceStateTransitionAnimation(Launcher launcher, Workspace workspace)53 public WorkspaceStateTransitionAnimation(Launcher launcher, Workspace workspace) { 54 mLauncher = launcher; 55 mWorkspace = workspace; 56 } 57 setState(LauncherState toState)58 public void setState(LauncherState toState) { 59 setWorkspaceProperty(toState, NO_ANIM_PROPERTY_SETTER, new AnimatorSetBuilder(), 60 new AnimationConfig()); 61 } 62 setStateWithAnimation(LauncherState toState, AnimatorSetBuilder builder, AnimationConfig config)63 public void setStateWithAnimation(LauncherState toState, AnimatorSetBuilder builder, 64 AnimationConfig config) { 65 setWorkspaceProperty(toState, config.getPropertySetter(builder), builder, config); 66 } 67 getFinalScale()68 public float getFinalScale() { 69 return mNewScale; 70 } 71 72 /** 73 * Starts a transition animation for the workspace. 74 */ setWorkspaceProperty(LauncherState state, PropertySetter propertySetter, AnimatorSetBuilder builder, AnimationConfig config)75 private void setWorkspaceProperty(LauncherState state, PropertySetter propertySetter, 76 AnimatorSetBuilder builder, AnimationConfig config) { 77 ScaleAndTranslation scaleAndTranslation = state.getWorkspaceScaleAndTranslation(mLauncher); 78 ScaleAndTranslation hotseatScaleAndTranslation = state.getHotseatScaleAndTranslation( 79 mLauncher); 80 mNewScale = scaleAndTranslation.scale; 81 PageAlphaProvider pageAlphaProvider = state.getWorkspacePageAlphaProvider(mLauncher); 82 final int childCount = mWorkspace.getChildCount(); 83 for (int i = 0; i < childCount; i++) { 84 applyChildState(state, (CellLayout) mWorkspace.getChildAt(i), i, pageAlphaProvider, 85 propertySetter, builder, config); 86 } 87 88 int elements = state.getVisibleElements(mLauncher); 89 Interpolator fadeInterpolator = builder.getInterpolator(ANIM_WORKSPACE_FADE, 90 pageAlphaProvider.interpolator); 91 boolean playAtomicComponent = config.playAtomicOverviewScaleComponent(); 92 Hotseat hotseat = mWorkspace.getHotseat(); 93 if (playAtomicComponent) { 94 Interpolator scaleInterpolator = builder.getInterpolator(ANIM_WORKSPACE_SCALE, ZOOM_OUT); 95 propertySetter.setFloat(mWorkspace, SCALE_PROPERTY, mNewScale, scaleInterpolator); 96 97 if (!hotseat.getRotationMode().isTransposed) { 98 // Set the hotseat's pivot point to match the workspace's, so that it scales 99 // together. Since both hotseat and workspace can move, transform the point 100 // manually instead of using dragLayer.getDescendantCoordRelativeToSelf and 101 // related methods. 102 hotseat.setPivotY(mWorkspace.getPivotY() + mWorkspace.getTop() - hotseat.getTop()); 103 hotseat.setPivotX(mWorkspace.getPivotX() 104 + mWorkspace.getLeft() - hotseat.getLeft()); 105 } 106 float hotseatScale = hotseatScaleAndTranslation.scale; 107 Interpolator hotseatScaleInterpolator = builder.getInterpolator(ANIM_HOTSEAT_SCALE, 108 scaleInterpolator); 109 propertySetter.setFloat(hotseat, SCALE_PROPERTY, hotseatScale, 110 hotseatScaleInterpolator); 111 112 float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0; 113 propertySetter.setViewAlpha(hotseat, hotseatIconsAlpha, fadeInterpolator); 114 propertySetter.setViewAlpha(mLauncher.getWorkspace().getPageIndicator(), 115 hotseatIconsAlpha, fadeInterpolator); 116 } 117 118 if (!config.playNonAtomicComponent()) { 119 // Only the alpha and scale, handled above, are included in the atomic animation. 120 return; 121 } 122 123 Interpolator translationInterpolator = !playAtomicComponent 124 ? LINEAR 125 : builder.getInterpolator(ANIM_WORKSPACE_TRANSLATE, ZOOM_OUT); 126 propertySetter.setFloat(mWorkspace, View.TRANSLATION_X, 127 scaleAndTranslation.translationX, translationInterpolator); 128 propertySetter.setFloat(mWorkspace, View.TRANSLATION_Y, 129 scaleAndTranslation.translationY, translationInterpolator); 130 131 Interpolator hotseatTranslationInterpolator = builder.getInterpolator( 132 ANIM_HOTSEAT_TRANSLATE, translationInterpolator); 133 propertySetter.setFloat(hotseat, View.TRANSLATION_Y, 134 hotseatScaleAndTranslation.translationY, hotseatTranslationInterpolator); 135 propertySetter.setFloat(mWorkspace.getPageIndicator(), View.TRANSLATION_Y, 136 hotseatScaleAndTranslation.translationY, hotseatTranslationInterpolator); 137 138 setScrim(propertySetter, state); 139 } 140 setScrim(PropertySetter propertySetter, LauncherState state)141 public void setScrim(PropertySetter propertySetter, LauncherState state) { 142 WorkspaceAndHotseatScrim scrim = mLauncher.getDragLayer().getScrim(); 143 propertySetter.setFloat(scrim, SCRIM_PROGRESS, state.getWorkspaceScrimAlpha(mLauncher), 144 LINEAR); 145 propertySetter.setFloat(scrim, SYSUI_PROGRESS, state.hasSysUiScrim ? 1 : 0, LINEAR); 146 } 147 applyChildState(LauncherState state, CellLayout cl, int childIndex)148 public void applyChildState(LauncherState state, CellLayout cl, int childIndex) { 149 applyChildState(state, cl, childIndex, state.getWorkspacePageAlphaProvider(mLauncher), 150 NO_ANIM_PROPERTY_SETTER, new AnimatorSetBuilder(), new AnimationConfig()); 151 } 152 applyChildState(LauncherState state, CellLayout cl, int childIndex, PageAlphaProvider pageAlphaProvider, PropertySetter propertySetter, AnimatorSetBuilder builder, AnimationConfig config)153 private void applyChildState(LauncherState state, CellLayout cl, int childIndex, 154 PageAlphaProvider pageAlphaProvider, PropertySetter propertySetter, 155 AnimatorSetBuilder builder, AnimationConfig config) { 156 float pageAlpha = pageAlphaProvider.getPageAlpha(childIndex); 157 int drawableAlpha = Math.round(pageAlpha * (state.hasWorkspacePageBackground ? 255 : 0)); 158 159 if (config.playNonAtomicComponent()) { 160 propertySetter.setInt(cl.getScrimBackground(), 161 DRAWABLE_ALPHA, drawableAlpha, ZOOM_OUT); 162 } 163 if (config.playAtomicOverviewScaleComponent()) { 164 Interpolator fadeInterpolator = builder.getInterpolator(ANIM_WORKSPACE_FADE, 165 pageAlphaProvider.interpolator); 166 propertySetter.setFloat(cl.getShortcutsAndWidgets(), View.ALPHA, 167 pageAlpha, fadeInterpolator); 168 } 169 } 170 }