LauncherStateTransitionAnimation.java revision 2a87fe8c41338e746c6959d992edfeb9cb00bcc1
1b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/* 2b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Copyright (C) 2015 The Android Open Source Project 3b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * 4b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 5b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * you may not use this file except in compliance with the License. 6b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * You may obtain a copy of the License at 7b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * 8b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * http://www.apache.org/licenses/LICENSE-2.0 9b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * 10b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Unless required by applicable law or agreed to in writing, software 11b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * distributed under the License is distributed on an "AS IS" BASIS, 12b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * See the License for the specific language governing permissions and 14b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * limitations under the License. 15b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 16b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 17b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpackage com.android.launcher3; 18b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 19b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.Animator; 20b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.AnimatorListenerAdapter; 21b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.AnimatorSet; 22b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.ObjectAnimator; 23b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.PropertyValuesHolder; 24b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.TimeInterpolator; 257066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyalimport android.annotation.SuppressLint; 26b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.content.res.Resources; 27b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.util.Log; 28b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.View; 29b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.AccelerateInterpolator; 30b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.DecelerateInterpolator; 311558893b873cd55b2df779f594f1de3c370d3328Adam Cohen 325f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chungimport com.android.launcher3.allapps.AllAppsContainerView; 33091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 345d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyalimport com.android.launcher3.util.UiThreadCircularReveal; 353f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport com.android.launcher3.widget.WidgetsContainerView; 361558893b873cd55b2df779f594f1de3c370d3328Adam Cohen 37b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport java.util.HashMap; 38b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 39b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/** 40b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * TODO: figure out what kind of tests we can write for this 41b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * 42b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Things to test when changing the following class. 43b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Home from workspace 44b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from center screen 45b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from other screens 46b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Home from all apps 47b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from center screen 48b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from other screens 49b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Back from all apps 50b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from center screen 51b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from other screens 52b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Launch app from workspace and quit 53b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 54b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 55b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Launch app from all apps and quit 56b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 57b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 58b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Go to a screen that's not the default, then all 59b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * apps, and launch and app, and go back 60b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 61b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * -with home 62b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On workspace, long press power and go back 63b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 64b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 65b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On all apps, long press power and go back 66b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 67b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 68b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On workspace, power off 69b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On all apps, power off 70b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Launch an app and turn off the screen while in that app 71b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Go back with home key 72b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Go back with back key TODO: make this not go to workspace 73b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From all apps 74b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From workspace 75b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Enter and exit car mode (becuase it causes an extra configuration changed) 76b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From all apps 77b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From the center workspace 78b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From another workspace 79b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 80b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpublic class LauncherStateTransitionAnimation { 81b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 82b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 83b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Private callbacks made during transition setup. 84b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 85b745afbdd75157c73d581b345118cdaff99e912dWinson Chung static abstract class PrivateTransitionCallbacks { 86b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewFinalAlpha(View revealView) { 87b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return 0; 88b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 89b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewStartFinalRadius() { 90b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return 0; 91b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 92b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(View revealView, 9398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song View buttonView) { 94b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return null; 95b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 9676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung void onTransitionComplete() {} 97b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 98b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 99b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public static final String TAG = "LauncherStateTransitionAnimation"; 100b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 101b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Flags to determine how to set the layers on views before the transition animation 102b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public static final int BUILD_LAYER = 0; 103b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public static final int BUILD_AND_SET_LAYER = 1; 104b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public static final int SINGLE_FRAME_DELAY = 16; 105b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 106091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk Launcher mLauncher; 107006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung @Thunk AnimatorSet mCurrentAnimation; 108b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 109006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung public LauncherStateTransitionAnimation(Launcher l) { 110b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mLauncher = l; 111b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 112b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 113b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 114b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts an animation to the apps view. 11576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * 11676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * @param startSearchAfterTransition Immediately starts app search after the transition to 11776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * All Apps is completed. 118b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 119006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung public void startAnimationToAllApps(final Workspace.State fromWorkspaceState, 120006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final boolean animated, final boolean startSearchAfterTransition) { 1215f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final AllAppsContainerView toView = mLauncher.getAppsView(); 12298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View buttonView = mLauncher.getAllAppsButton(); 123b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() { 124b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 125b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public float getMaterialRevealViewFinalAlpha(View revealView) { 126b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return 1f; 127b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 128b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 129b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public float getMaterialRevealViewStartFinalRadius() { 1302e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; 131b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return allAppsButtonSize / 2; 132b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 133b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 134b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 135b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View revealView, final View allAppsButtonView) { 136b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 137b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationStart(Animator animation) { 138b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.INVISIBLE); 139b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 140b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 141b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.VISIBLE); 142b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 143b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 144b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 14576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung @Override 14676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung void onTransitionComplete() { 14776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung if (startSearchAfterTransition) { 14876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung toView.startAppsSearch(); 14976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung } 15076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung } 151b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 152ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating from spring loaded mode back to all apps 153006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState, 154006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung Workspace.State.NORMAL_HIDDEN, buttonView, toView, toView.getContentView(), 155006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung toView.getRevealView(), toView.getSearchBarView(), animated, cb); 156b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 157b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 158b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 159b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts an animation to the widgets view. 160b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 161006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung public void startAnimationToWidgets(final Workspace.State fromWorkspaceState, 162006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final boolean animated) { 1633f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song final WidgetsContainerView toView = mLauncher.getWidgetsView(); 16498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View buttonView = mLauncher.getWidgetsButton(); 165b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() { 166b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 167b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public float getMaterialRevealViewFinalAlpha(View revealView) { 168b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return 0.3f; 169b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 170b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 171006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState, 172006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung Workspace.State.OVERVIEW_HIDDEN, buttonView, toView, toView.getContentView(), 173006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung toView.getRevealView(), null, animated, cb); 174b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 175b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 176b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 177b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts and animation to the workspace from the current overlay view. 178b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 179b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void startAnimationToWorkspace(final Launcher.State fromState, 180006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 1812a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final boolean animated, final Runnable onCompleteRunnable) { 182b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (toWorkspaceState != Workspace.State.NORMAL && 183b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspaceState != Workspace.State.SPRING_LOADED && 184b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspaceState != Workspace.State.OVERVIEW) { 185b745afbdd75157c73d581b345118cdaff99e912dWinson Chung Log.e(TAG, "Unexpected call to startAnimationToWorkspace"); 186b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 187b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 188b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED) { 1892a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson startAnimationToWorkspaceFromAllApps(fromWorkspaceState, toWorkspaceState, 190dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung animated, onCompleteRunnable); 191b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 1922a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson startAnimationToWorkspaceFromWidgets(fromWorkspaceState, toWorkspaceState, 193dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung animated, onCompleteRunnable); 194b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 195b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 196b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 197b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 198b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to a particular overlay view. 199b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 2007066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal @SuppressLint("NewApi") 201006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private AnimatorSet startAnimationToOverlay(final Workspace.State fromWorkspaceState, 202006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final Workspace.State toWorkspaceState, final View buttonView, final View toView, 203006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final View contentView, final View revealView, final View overlaySearchBarView, 204006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final boolean animated, final PrivateTransitionCallbacks pCb) { 205006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 206b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 207b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final boolean material = Utilities.isLmpOrAbove(); 2085f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 209b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final int itemsAlphaStagger = 2105f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung res.getInteger(R.integer.config_overlayItemsAlphaStagger); 211b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 212b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View fromView = mLauncher.getWorkspace(); 213b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 214b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final HashMap<View, Integer> layerViews = new HashMap<>(); 215b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 216b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 21798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 218b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 219b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 220b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 221b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 222b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the workspace animation. 223b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // NOTE: this call apparently also sets the state for the workspace if !animated 224ce5a7e5ee4c880081faef3a508f68725d0317ee9Sunny Goyal Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState, 225006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animated, layerViews); 226b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 227006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Animate the search bar 228006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung startWorkspaceSearchBarAnimation(animation, fromWorkspaceState, toWorkspaceState, 229006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animated ? revealDuration : 0, overlaySearchBarView); 230b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 231006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (animated && initialized) { 232b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the reveal view animation 233b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 234b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 235f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 236b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 237b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(0f); 238b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0f); 239b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationX(0f); 240b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 241b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 242b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha; 243b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 244b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 245b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 24698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, 24798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song buttonView, null); 248b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToAlpha = pCb.getMaterialRevealViewFinalAlpha(revealView); 24998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 25098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 251b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 252b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToAlpha = 0f; 253b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 254b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 255b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 256b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 257b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the animators 258b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelAlpha = 2595d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f); 260b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftY = 2615d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0); 262b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftX = 2635d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0); 264b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView, 265b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha, panelDriftY, panelDriftX); 266b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setDuration(revealDuration); 267b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 268b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 269b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Play the animation 270b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(revealView, BUILD_AND_SET_LAYER); 271006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlphaAndDrift); 272b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 273ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (overlaySearchBarView != null) { 274ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung overlaySearchBarView.setAlpha(0f); 275ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung ObjectAnimator searchBarAlpha = ObjectAnimator.ofFloat(overlaySearchBarView, "alpha", 0f, 1f); 276ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung searchBarAlpha.setDuration(100); 277ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung searchBarAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 278ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung layerViews.put(overlaySearchBarView, BUILD_AND_SET_LAYER); 279006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(searchBarAlpha); 280ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 281ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 282b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 283b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setVisibility(View.VISIBLE); 284b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(0f); 285b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(revealViewToYDrift); 286b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(contentView, BUILD_AND_SET_LAYER); 287b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 289b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift, 0); 291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration); 292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger); 294006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 295b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f); 297b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(revealDuration); 298b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 299b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setStartDelay(itemsAlphaStagger); 300006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 301b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 302b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float startRadius = pCb.getMaterialRevealViewStartFinalRadius(); 304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener( 30598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealView, buttonView); 3061558893b873cd55b2df779f594f1de3c370d3328Adam Cohen Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2, 307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung height / 2, startRadius, revealRadius); 308b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 309b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 311b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 312b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 313006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(reveal); 314b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 316006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, false); 320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, false); 321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 322b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 323b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Disable all necessary layers 326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 328b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_NONE, null); 329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 333006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 33476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 335b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 336b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 337b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 338b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Play the workspace animation 340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (workspaceAnim != null) { 341006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(workspaceAnim); 342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 343b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 344b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Dispatch the prepare transition signal 345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, false); 346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, false); 347b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 348b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 349006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet stateAnimation = animation; 350b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Runnable startAnimRunnable = new Runnable() { 351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void run() { 352006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Check that mCurrentAnimation hasn't changed while 353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // we waited for a layout/draw pass 354006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != stateAnimation) 355b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return; 356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 357b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Enable all necessary layers 36011509ad61afb7424ce83057b0d2a4b09f853651fWinson Chung boolean isLmpOrAbove = Utilities.isLmpOrAbove(); 361b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 36511509ad61afb7424ce83057b0d2a4b09f853651fWinson Chung if (isLmpOrAbove && Utilities.isViewAttachedToWindow(v)) { 366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.buildLayer(); 367b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Focus the new view 371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.requestFocus(); 372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 373006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung stateAnimation.start(); 374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 375b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 376b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.bringToFront(); 377b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setVisibility(View.VISIBLE); 378b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.post(startAnimRunnable); 379006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 380006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung return animation; 381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setTranslationX(0.0f); 383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setTranslationY(0.0f); 384b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setScaleX(1.0f); 385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setScaleY(1.0f); 386b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setVisibility(View.VISIBLE); 387b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.bringToFront(); 388b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 389b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Show the content view 390b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setVisibility(View.VISIBLE); 391b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 392b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, false); 393b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 394b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, false); 395b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, false); 396b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 397b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, false); 39876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 399006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 400006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung return null; 401b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 402b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 403b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 404b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 405b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts and animation to the workspace from the apps view. 406b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 407006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState, 4082a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Workspace.State toWorkspaceState, final boolean animated, 4092a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 4105f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung AllAppsContainerView appsView = mLauncher.getAppsView(); 411b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() { 412b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 413b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewFinalAlpha(View revealView) { 414b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // No alpha anim from all apps 415b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return 1f; 416b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 417b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 418b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewStartFinalRadius() { 4192e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; 420b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return allAppsButtonSize / 2; 421b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 422b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 423b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 424b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View revealView, final View allAppsButtonView) { 425b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 426b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationStart(Animator animation) { 427b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // We set the alpha instead of visibility to ensure that the focus does not 428b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // get taken from the all apps view 429b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.VISIBLE); 430b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(0f); 431b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 432b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 433b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 434b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 435b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 436b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Show the all apps button, and focus it 437b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(1f); 438b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 439b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 440b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 441b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 442ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating to spring loaded mode from all apps 443006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState, 4442a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson mLauncher.getAllAppsButton(), appsView, appsView.getContentView(), 44598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song appsView.getRevealView(), appsView.getSearchBarView(), animated, 44698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song onCompleteRunnable, cb); 447b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 448b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 449b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 450b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts and animation to the workspace from the widgets view. 451b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 452006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState, 4532a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Workspace.State toWorkspaceState, final boolean animated, 4542a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 4554cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song final WidgetsContainerView widgetsView = mLauncher.getWidgetsView(); 456b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() { 457b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 458b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewFinalAlpha(View revealView) { 45998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song return 0.3f; 460b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 461b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 462b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 46398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View revealView, final View widgetsButtonView) { 464b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 465b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 466b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 467b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 468b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 469b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 470b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 471b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 472006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = startAnimationToWorkspaceFromOverlay(fromWorkspaceState, 4732a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson toWorkspaceState, mLauncher.getWidgetsButton(), widgetsView, 474006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung widgetsView.getContentView(), widgetsView.getRevealView(), null, animated, 475006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung onCompleteRunnable, cb); 476b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 477b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 478b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 479b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to the workspace. 480b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 481006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private AnimatorSet startAnimationToWorkspaceFromOverlay(final Workspace.State fromWorkspaceState, 4822a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Workspace.State toWorkspaceState, final View buttonView, 483006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final View fromView, final View contentView, final View revealView, 484006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final View overlaySearchBarView, final boolean animated, final Runnable onCompleteRunnable, 485006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final PrivateTransitionCallbacks pCb) { 486006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 487b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 488b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final boolean material = Utilities.isLmpOrAbove(); 4895f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 490b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final int itemsAlphaStagger = 4915f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung res.getInteger(R.integer.config_overlayItemsAlphaStagger); 492b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 493b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View toView = mLauncher.getWorkspace(); 494b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 495b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final HashMap<View, Integer> layerViews = new HashMap<>(); 496b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 497b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 49898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 499b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 500b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 501b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 502b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 503b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the workspace animation. 504b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // NOTE: this call apparently also sets the state for the workspace if !animated 505cd99cd3ed6a84b9dcd8f4c60b0941760f85a64ceWinson Chung Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState, 5062a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson animated, layerViews); 507b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 508006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Animate the search bar 509006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung startWorkspaceSearchBarAnimation(animation, fromWorkspaceState, toWorkspaceState, 510006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animated ? revealDuration : 0, overlaySearchBarView); 511b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 512006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (animated && initialized) { 513b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Play the workspace animation 514b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (workspaceAnim != null) { 515006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(workspaceAnim); 516b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 517b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 518b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // hideAppsCustomizeHelper is called in some cases when it is already hidden 519b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // don't perform all these no-op animations. In particularly, this was causing 520b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // the all-apps button to pop in and out. 521b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (fromView.getVisibility() == View.VISIBLE) { 522b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 523b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 524f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 525b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 526b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(1f); 527b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0); 528b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(revealView, BUILD_AND_SET_LAYER); 529b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 530b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 531b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 532b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 533b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 53498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, 53598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song buttonView, null); 53698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 53798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 538b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 539b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 540b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 541b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 542b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 543b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // The vertical motion of the apps panel should be delayed by one frame 544b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // from the conceal animation in order to give the right feel. We correspondingly 545b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // shorten the duration so that the slide and conceal end at the same time. 546b745afbdd75157c73d581b345118cdaff99e912dWinson Chung TimeInterpolator decelerateInterpolator = material ? 547b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new LogDecelerateInterpolator(100, 0) : 548b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new DecelerateInterpolator(1f); 5491558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY", 550b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 551b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY); 552b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 553b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setInterpolator(decelerateInterpolator); 554006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftY); 555b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 5561558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX", 557b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToXDrift); 558b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY); 559b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 560b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setInterpolator(decelerateInterpolator); 561006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftX); 562b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 563b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup animation for the reveal panel alpha 564b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha = !material ? 0f : 565b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pCb.getMaterialRevealViewFinalAlpha(revealView); 566b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (revealViewToAlpha != 1f) { 5671558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha", 568b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1f, revealViewToAlpha); 569b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setDuration(material ? revealDuration : 150); 570b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY); 571b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setInterpolator(decelerateInterpolator); 572006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlpha); 573b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 574b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 575b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 576b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(contentView, BUILD_AND_SET_LAYER); 577b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 578b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 5791558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 580b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 581b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 582b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY); 583b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(decelerateInterpolator); 584b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 585006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 586b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 587b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1f); 5881558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f); 589b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(100); 590b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(decelerateInterpolator); 591006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 592b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 593ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (overlaySearchBarView != null) { 594ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung overlaySearchBarView.setAlpha(1f); 595ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung ObjectAnimator searchAlpha = ObjectAnimator.ofFloat(overlaySearchBarView, "alpha", 1f, 0f); 596ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung searchAlpha.setDuration(material ? 100 : 150); 597ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung searchAlpha.setInterpolator(decelerateInterpolator); 598ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung searchAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY); 599ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung layerViews.put(overlaySearchBarView, BUILD_AND_SET_LAYER); 600006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(searchAlpha); 601ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 602ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 603b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 604b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Animate the all apps button 605b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float finalRadius = pCb.getMaterialRevealViewStartFinalRadius(); 606b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = 60798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView); 6081558893b873cd55b2df779f594f1de3c370d3328Adam Cohen Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2, 6091558893b873cd55b2df779f594f1de3c370d3328Adam Cohen height / 2, revealRadius, finalRadius); 610b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 611b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 612b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setStartDelay(itemsAlphaStagger); 613b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 614b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 615b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 616006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(reveal); 617b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 618b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 619b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, true); 620b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, true); 621b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 622b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 623006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 624b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 625b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 626b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.setVisibility(View.GONE); 627b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, true); 628b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, true); 629b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 630b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Run any queued runnables 631b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (onCompleteRunnable != null) { 632b745afbdd75157c73d581b345118cdaff99e912dWinson Chung onCompleteRunnable.run(); 633b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 634b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 635b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Disable all necessary layers 636b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 637b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 638b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_NONE, null); 639b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 640b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 641b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 642b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Reset page transforms 643b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (contentView != null) { 644b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationX(0); 645b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 646b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1); 647b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 648ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (overlaySearchBarView != null) { 649ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung overlaySearchBarView.setAlpha(1f); 650ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 651b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 652b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 653006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 65476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 655b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 656b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 657b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 658006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet stateAnimation = animation; 659b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Runnable startAnimRunnable = new Runnable() { 660b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void run() { 661006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Check that mCurrentAnimation hasn't changed while 662b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // we waited for a layout/draw pass 663006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != stateAnimation) 664b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return; 665006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 666b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 667b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 668b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 669b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Enable all necessary layers 67011509ad61afb7424ce83057b0d2a4b09f853651fWinson Chung boolean isLmpOrAbove = Utilities.isLmpOrAbove(); 671b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 672b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 673b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 674b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 67511509ad61afb7424ce83057b0d2a4b09f853651fWinson Chung if (isLmpOrAbove && Utilities.isViewAttachedToWindow(v)) { 676b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.buildLayer(); 677b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 678b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 679006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung stateAnimation.start(); 680b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 681b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 682b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.post(startAnimRunnable); 683006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 684006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung return animation; 685b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 686b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.setVisibility(View.GONE); 687b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, true); 688b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, true); 689b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, true); 690b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, true); 691b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, true); 692b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, true); 69376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 694b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 695b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Run any queued runnables 696b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (onCompleteRunnable != null) { 697b745afbdd75157c73d581b345118cdaff99e912dWinson Chung onCompleteRunnable.run(); 698b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 699006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 700006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung return null; 701b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 702b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 703b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 704006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung /** 705006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung * Coordinates the workspace search bar animation along with the launcher state animation. 706006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung */ 707006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startWorkspaceSearchBarAnimation(AnimatorSet animation, 708006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, int duration, 709006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung View overlaySearchBar) { 710006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final SearchDropTargetBar.State toSearchBarState = 711006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung toWorkspaceState.getSearchDropTargetBarState(); 712006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 713006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (overlaySearchBar != null) { 714006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if ((toWorkspaceState == Workspace.State.NORMAL) && 715006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung (fromWorkspaceState == Workspace.State.NORMAL_HIDDEN)) { 716006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // If we are transitioning from the overlay to the workspace, then show the 717006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // workspace search bar immediately and let the overlay search bar fade out on top 718006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState, 0); 719006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung } else if (fromWorkspaceState == Workspace.State.NORMAL) { 720006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // If we are transitioning from the workspace to the overlay, then keep the 721006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // workspace search bar visible until the overlay search bar fades in on top 722006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 723006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung @Override 724006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung public void onAnimationEnd(Animator animation) { 725006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState, 0); 726006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung } 727006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung }); 728006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung } else { 729006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Otherwise, then just animate the workspace search bar normally 730006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState, duration); 731006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung } 732006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung } else { 733006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // If there is no overlay search bar, then just animate the workspace search bar 734006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState, duration); 735006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung } 736006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung } 737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 738b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 739b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the prepare-transition event to suitable views. 740b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) { 742b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 743b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated, 744b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 745b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 746b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 747b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 748b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the start-transition event to suitable views. 750b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) { 752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated, 754b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 755b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 756b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Update the workspace transition step as well 758b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStep(v, 0f); 759b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 760b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 761b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 762b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the step-transition event to suitable views. 763b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 764b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionStep(View v, float t) { 765b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 766b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t); 767b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 768b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 769b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 770b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 771b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the end-transition event to suitable views. 772b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 773b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) { 774b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 775b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated, 776b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 777b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 778b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 779b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Update the workspace transition step as well 780b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStep(v, 1f); 781b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 782b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 783b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 784b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Cancels the current animation. 785b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 786b745afbdd75157c73d581b345118cdaff99e912dWinson Chung private void cancelAnimation() { 787006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != null) { 788006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.setDuration(0); 789006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.cancel(); 790006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 791b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 792b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 793006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 794006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void cleanupAnimation() { 795006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 796006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung } 7971558893b873cd55b2df779f594f1de3c370d3328Adam Cohen} 798