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