LauncherStateTransitionAnimation.java revision 5d2fc32e6da66f877dfba4fe513fbabdcdae5f99
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 * Callbacks made during the state transition 84b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 85b745afbdd75157c73d581b345118cdaff99e912dWinson Chung interface Callbacks { 86b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onStateTransitionHideSearchBar(); 87b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 88b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 89b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 90b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Private callbacks made during transition setup. 91b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 92b745afbdd75157c73d581b345118cdaff99e912dWinson Chung static abstract class PrivateTransitionCallbacks { 93b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewFinalAlpha(View revealView) { 94b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return 0; 95b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 96b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewStartFinalRadius() { 97b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return 0; 98b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 99b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(View revealView, 10098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song View buttonView) { 101b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return null; 102b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 10376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung void onTransitionComplete() {} 104b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 105b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 106b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public static final String TAG = "LauncherStateTransitionAnimation"; 107b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 108b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Flags to determine how to set the layers on views before the transition animation 109b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public static final int BUILD_LAYER = 0; 110b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public static final int BUILD_AND_SET_LAYER = 1; 111b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public static final int SINGLE_FRAME_DELAY = 16; 112b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 113091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk Launcher mLauncher; 114091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk Callbacks mCb; 115091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk AnimatorSet mStateAnimation; 116b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 117b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public LauncherStateTransitionAnimation(Launcher l, Callbacks cb) { 118b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mLauncher = l; 119b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mCb = cb; 120b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 121b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 122b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 123b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts an animation to the apps view. 12476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * 12576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * @param startSearchAfterTransition Immediately starts app search after the transition to 12676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * All Apps is completed. 127b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 12876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung public void startAnimationToAllApps(final boolean animated, 12976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung final boolean startSearchAfterTransition) { 1305f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final AllAppsContainerView toView = mLauncher.getAppsView(); 13198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View buttonView = mLauncher.getAllAppsButton(); 132b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() { 133b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 134b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public float getMaterialRevealViewFinalAlpha(View revealView) { 135b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return 1f; 136b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 137b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 138b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public float getMaterialRevealViewStartFinalRadius() { 1392e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; 140b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return allAppsButtonSize / 2; 141b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 142b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 143b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 144b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View revealView, final View allAppsButtonView) { 145b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 146b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationStart(Animator animation) { 147b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.INVISIBLE); 148b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 149b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 150b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.VISIBLE); 151b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 152b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 153b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 15476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung @Override 15576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung void onTransitionComplete() { 15676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung if (startSearchAfterTransition) { 15776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung toView.startAppsSearch(); 15876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung } 15976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung } 160b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 161ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating from spring loaded mode back to all apps 16298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song startAnimationToOverlay(Workspace.State.NORMAL_HIDDEN, buttonView, toView, 16398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song toView.getContentView(), toView.getRevealView(), toView.getSearchBarView(), 16498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song animated, true /* hideSearchBar */, cb); 165b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 166b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 167b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 168b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts an animation to the widgets view. 169b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 170b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void startAnimationToWidgets(final boolean animated) { 1713f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song final WidgetsContainerView toView = mLauncher.getWidgetsView(); 17298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View buttonView = mLauncher.getWidgetsButton(); 173b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() { 174b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 175b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public float getMaterialRevealViewFinalAlpha(View revealView) { 176b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return 0.3f; 177b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 178b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 17998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song startAnimationToOverlay(Workspace.State.OVERVIEW_HIDDEN, buttonView, toView, 180ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung toView.getContentView(), toView.getRevealView(), null, animated, 181ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung true /* hideSearchBar */, cb); 182b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 183b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 184b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 185b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts and animation to the workspace from the current overlay view. 186b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 187b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void startAnimationToWorkspace(final Launcher.State fromState, 188ce5a7e5ee4c880081faef3a508f68725d0317ee9Sunny Goyal final Workspace.State toWorkspaceState, 189dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung final boolean animated, final Runnable onCompleteRunnable) { 190b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (toWorkspaceState != Workspace.State.NORMAL && 191b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspaceState != Workspace.State.SPRING_LOADED && 192b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspaceState != Workspace.State.OVERVIEW) { 193b745afbdd75157c73d581b345118cdaff99e912dWinson Chung Log.e(TAG, "Unexpected call to startAnimationToWorkspace"); 194b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 195b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 196b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED) { 197ce5a7e5ee4c880081faef3a508f68725d0317ee9Sunny Goyal startAnimationToWorkspaceFromAllApps(toWorkspaceState, animated, onCompleteRunnable); 198b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 199ce5a7e5ee4c880081faef3a508f68725d0317ee9Sunny Goyal startAnimationToWorkspaceFromWidgets(toWorkspaceState, animated, onCompleteRunnable); 200b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 201b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 202b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 203b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 204b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to a particular overlay view. 205b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 2067066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal @SuppressLint("NewApi") 20798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song private void startAnimationToOverlay(final Workspace.State toWorkspaceState, 20898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View buttonView, final View toView, final View contentView, final View revealView, 20998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View overlaySearchBarView, final boolean animated, final boolean hideSearchBar, 21098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final PrivateTransitionCallbacks pCb) { 211b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 212b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final boolean material = Utilities.isLmpOrAbove(); 2135f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 214b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final int itemsAlphaStagger = 2155f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung res.getInteger(R.integer.config_overlayItemsAlphaStagger); 216b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 217b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View fromView = mLauncher.getWorkspace(); 218b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 219b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final HashMap<View, Integer> layerViews = new HashMap<>(); 220b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 221b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 22298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 223b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 224b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 225b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 226b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 227b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the workspace animation. 228b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // NOTE: this call apparently also sets the state for the workspace if !animated 229ce5a7e5ee4c880081faef3a508f68725d0317ee9Sunny Goyal Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState, 230ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung animated, overlaySearchBarView != null /* hasOverlaySearchBar */, layerViews); 231b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 232b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (animated && initialized) { 233b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation = LauncherAnimUtils.createAnimatorSet(); 234b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 235b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the reveal view animation 236b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 237b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 238f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 239b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 240b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(0f); 241b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0f); 242b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationX(0f); 243b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 244b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 245b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha; 246b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 247b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 248b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 24998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, 25098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song buttonView, null); 251b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToAlpha = pCb.getMaterialRevealViewFinalAlpha(revealView); 25298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 25398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 254b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 255b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToAlpha = 0f; 256b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 257b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 258b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 259b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 260b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the animators 261b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelAlpha = 2625d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f); 263b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftY = 2645d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0); 265b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftX = 2665d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0); 267b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView, 268b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha, panelDriftY, panelDriftX); 269b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setDuration(revealDuration); 270b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 271b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 272b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Play the animation 273b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(revealView, BUILD_AND_SET_LAYER); 274b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.play(panelAlphaAndDrift); 275b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 276ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (overlaySearchBarView != null) { 277ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung overlaySearchBarView.setAlpha(0f); 278ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung ObjectAnimator searchBarAlpha = ObjectAnimator.ofFloat(overlaySearchBarView, "alpha", 0f, 1f); 279ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung searchBarAlpha.setDuration(100); 280ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung searchBarAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 281ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung layerViews.put(overlaySearchBarView, BUILD_AND_SET_LAYER); 282ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mStateAnimation.play(searchBarAlpha); 283ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 284ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 285b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 286b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setVisibility(View.VISIBLE); 287b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(0f); 288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(revealViewToYDrift); 289b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(contentView, BUILD_AND_SET_LAYER); 290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift, 0); 294b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration); 295b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger); 297b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.play(pageDrift); 298b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 299b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f); 300b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(revealDuration); 301b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 302b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setStartDelay(itemsAlphaStagger); 303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.play(itemsAlpha); 304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 305b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float startRadius = pCb.getMaterialRevealViewStartFinalRadius(); 307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener( 30898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealView, buttonView); 3091558893b873cd55b2df779f594f1de3c370d3328Adam Cohen Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2, 310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung height / 2, startRadius, revealRadius); 311b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 312b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 313b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 314b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 316b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.play(reveal); 317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.addListener(new AnimatorListenerAdapter() { 320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 322b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, false); 323b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, false); 324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 328b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Disable all necessary layers 329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_NONE, null); 332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 3350f785720667ab8afe4b4620a6c333d382d8659edWinson Chung if (hideSearchBar) { 3360f785720667ab8afe4b4620a6c333d382d8659edWinson Chung mCb.onStateTransitionHideSearchBar(); 3370f785720667ab8afe4b4620a6c333d382d8659edWinson Chung } 338b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation = null; 34176648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 343b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 344b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Play the workspace animation 347b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (workspaceAnim != null) { 348b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.play(workspaceAnim); 349b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 350b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Dispatch the prepare transition signal 352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, false); 353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, false); 354b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 355b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final AnimatorSet stateAnimation = mStateAnimation; 357b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Runnable startAnimRunnable = new Runnable() { 358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void run() { 359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Check that mStateAnimation hasn't changed while 360b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // we waited for a layout/draw pass 361b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (mStateAnimation != stateAnimation) 362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return; 363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Enable all necessary layers 36711509ad61afb7424ce83057b0d2a4b09f853651fWinson Chung boolean isLmpOrAbove = Utilities.isLmpOrAbove(); 368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 37211509ad61afb7424ce83057b0d2a4b09f853651fWinson Chung if (isLmpOrAbove && Utilities.isViewAttachedToWindow(v)) { 373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.buildLayer(); 374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 375b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 376b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 377b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Focus the new view 378b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.requestFocus(); 379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 380b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.start(); 381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.bringToFront(); 384b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setVisibility(View.VISIBLE); 385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.post(startAnimRunnable); 386b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 387b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setTranslationX(0.0f); 388b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setTranslationY(0.0f); 389b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setScaleX(1.0f); 390b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setScaleY(1.0f); 391b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setVisibility(View.VISIBLE); 392b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.bringToFront(); 393b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 394b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Show the content view 395b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setVisibility(View.VISIBLE); 396b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 3970f785720667ab8afe4b4620a6c333d382d8659edWinson Chung if (hideSearchBar) { 3980f785720667ab8afe4b4620a6c333d382d8659edWinson Chung mCb.onStateTransitionHideSearchBar(); 3990f785720667ab8afe4b4620a6c333d382d8659edWinson Chung } 400b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 401b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, false); 402b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 403b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, false); 404b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, false); 405b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 406b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, false); 40776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 408b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 409b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 410b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 411b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 412b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts and animation to the workspace from the apps view. 413b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 414ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung private void startAnimationToWorkspaceFromAllApps(final Workspace.State toWorkspaceState, 415ce5a7e5ee4c880081faef3a508f68725d0317ee9Sunny Goyal final boolean animated, final Runnable onCompleteRunnable) { 4165f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung AllAppsContainerView appsView = mLauncher.getAppsView(); 417b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() { 418b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int[] mAllAppsToPanelDelta; 419b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 420b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 421b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewFinalAlpha(View revealView) { 422b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // No alpha anim from all apps 423b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return 1f; 424b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 425b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 426b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewStartFinalRadius() { 4272e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; 428b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return allAppsButtonSize / 2; 429b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 430b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 431b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 432b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View revealView, final View allAppsButtonView) { 433b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 434b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationStart(Animator animation) { 435b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // We set the alpha instead of visibility to ensure that the focus does not 436b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // get taken from the all apps view 437b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.VISIBLE); 438b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(0f); 439b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 440b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 441b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 442b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 443b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 444b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Show the all apps button, and focus it 445b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(1f); 446b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 447b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 448b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 449b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 450ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating to spring loaded mode from all apps 451b4a367459a6e99f4740eea5816dac70967384803Hyunyoung Song startAnimationToWorkspaceFromOverlay(toWorkspaceState, mLauncher.getAllAppsButton(), 452b4a367459a6e99f4740eea5816dac70967384803Hyunyoung Song appsView, appsView.getContentView(), appsView.getRevealView(), 453b4a367459a6e99f4740eea5816dac70967384803Hyunyoung Song appsView.getSearchBarView(), animated, onCompleteRunnable, cb); 454b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 455b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 456b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 457b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts and animation to the workspace from the widgets view. 458b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 459ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung private void startAnimationToWorkspaceFromWidgets(final Workspace.State toWorkspaceState, 460ce5a7e5ee4c880081faef3a508f68725d0317ee9Sunny Goyal final boolean animated, final Runnable onCompleteRunnable) { 4614cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song final WidgetsContainerView widgetsView = mLauncher.getWidgetsView(); 462b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() { 463b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 464b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewFinalAlpha(View revealView) { 46598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song return 0.3f; 466b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 467b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 468b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 46998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View revealView, final View widgetsButtonView) { 470b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 471b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 472b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 473b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 474b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 475b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 476b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 477b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 478b4a367459a6e99f4740eea5816dac70967384803Hyunyoung Song startAnimationToWorkspaceFromOverlay(toWorkspaceState, mLauncher.getWidgetsButton(), 479b4a367459a6e99f4740eea5816dac70967384803Hyunyoung Song widgetsView, widgetsView.getContentView(), widgetsView.getRevealView(), null, 480b4a367459a6e99f4740eea5816dac70967384803Hyunyoung Song animated, onCompleteRunnable, cb); 481b4a367459a6e99f4740eea5816dac70967384803Hyunyoung Song } 482b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 483b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 484b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to the workspace. 485b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 486b745afbdd75157c73d581b345118cdaff99e912dWinson Chung private void startAnimationToWorkspaceFromOverlay(final Workspace.State toWorkspaceState, 487b4a367459a6e99f4740eea5816dac70967384803Hyunyoung Song final View buttonView, final View fromView, final View contentView, 488ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung final View revealView, final View overlaySearchBarView, final boolean animated, 489ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung final Runnable onCompleteRunnable, final PrivateTransitionCallbacks pCb) { 490b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 491b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final boolean material = Utilities.isLmpOrAbove(); 4925f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 493b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final int itemsAlphaStagger = 4945f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung res.getInteger(R.integer.config_overlayItemsAlphaStagger); 495b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 496b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View toView = mLauncher.getWorkspace(); 497b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 498b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final HashMap<View, Integer> layerViews = new HashMap<>(); 499b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 500b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 50198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 502b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 503b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 504b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 505b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 506b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the workspace animation. 507b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // NOTE: this call apparently also sets the state for the workspace if !animated 508cd99cd3ed6a84b9dcd8f4c60b0941760f85a64ceWinson Chung Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState, 509ce5a7e5ee4c880081faef3a508f68725d0317ee9Sunny Goyal animated, overlaySearchBarView != null /* hasOverlaySearchBar */, 510ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung layerViews); 511b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 512b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (animated && initialized) { 513b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation = LauncherAnimUtils.createAnimatorSet(); 514b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 515b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Play the workspace animation 516b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (workspaceAnim != null) { 517b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.play(workspaceAnim); 518b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 519b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 520b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // hideAppsCustomizeHelper is called in some cases when it is already hidden 521b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // don't perform all these no-op animations. In particularly, this was causing 522b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // the all-apps button to pop in and out. 523b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (fromView.getVisibility() == View.VISIBLE) { 524b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 525b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 526f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 527b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 528b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(1f); 529b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0); 530b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(revealView, BUILD_AND_SET_LAYER); 531b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 532b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 533b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 534b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 535b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 53698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, 53798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song buttonView, null); 53898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 53998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 540b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 541b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 542b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 543b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 544b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 545b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // The vertical motion of the apps panel should be delayed by one frame 546b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // from the conceal animation in order to give the right feel. We correspondingly 547b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // shorten the duration so that the slide and conceal end at the same time. 548b745afbdd75157c73d581b345118cdaff99e912dWinson Chung TimeInterpolator decelerateInterpolator = material ? 549b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new LogDecelerateInterpolator(100, 0) : 550b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new DecelerateInterpolator(1f); 5511558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY", 552b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 553b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY); 554b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 555b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setInterpolator(decelerateInterpolator); 556b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.play(panelDriftY); 557b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 5581558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX", 559b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToXDrift); 560b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY); 561b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 562b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setInterpolator(decelerateInterpolator); 563b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.play(panelDriftX); 564b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 565b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup animation for the reveal panel alpha 566b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha = !material ? 0f : 567b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pCb.getMaterialRevealViewFinalAlpha(revealView); 568b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (revealViewToAlpha != 1f) { 5691558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha", 570b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1f, revealViewToAlpha); 571b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setDuration(material ? revealDuration : 150); 572b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY); 573b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setInterpolator(decelerateInterpolator); 574b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.play(panelAlpha); 575b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 576b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 577b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 578b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(contentView, BUILD_AND_SET_LAYER); 579b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 580b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 5811558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 582b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 583b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 584b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY); 585b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(decelerateInterpolator); 586b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 587b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.play(pageDrift); 588b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 589b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1f); 5901558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f); 591b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(100); 592b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(decelerateInterpolator); 593b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.play(itemsAlpha); 594b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 595ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (overlaySearchBarView != null) { 596ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung overlaySearchBarView.setAlpha(1f); 597ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung ObjectAnimator searchAlpha = ObjectAnimator.ofFloat(overlaySearchBarView, "alpha", 1f, 0f); 598ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung searchAlpha.setDuration(material ? 100 : 150); 599ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung searchAlpha.setInterpolator(decelerateInterpolator); 600ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung searchAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY); 601ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung layerViews.put(overlaySearchBarView, BUILD_AND_SET_LAYER); 602ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung mStateAnimation.play(searchAlpha); 603ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 604ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung 605b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 606b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Animate the all apps button 607b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float finalRadius = pCb.getMaterialRevealViewStartFinalRadius(); 608b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = 60998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView); 6101558893b873cd55b2df779f594f1de3c370d3328Adam Cohen Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2, 6111558893b873cd55b2df779f594f1de3c370d3328Adam Cohen height / 2, revealRadius, finalRadius); 612b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 613b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 614b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setStartDelay(itemsAlphaStagger); 615b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 616b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 617b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 618b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.play(reveal); 619b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 620b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 621b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, true); 622b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, true); 623b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 624b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 625b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.addListener(new AnimatorListenerAdapter() { 626b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 627b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 628b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.setVisibility(View.GONE); 629b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, true); 630b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, true); 631b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 632b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Run any queued runnables 633b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (onCompleteRunnable != null) { 634b745afbdd75157c73d581b345118cdaff99e912dWinson Chung onCompleteRunnable.run(); 635b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 636b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 637b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Disable all necessary layers 638b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 639b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 640b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_NONE, null); 641b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 642b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 643b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 644b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Reset page transforms 645b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (contentView != null) { 646b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationX(0); 647b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 648b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1); 649b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 650ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung if (overlaySearchBarView != null) { 651ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung overlaySearchBarView.setAlpha(1f); 652ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung } 653b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 654b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 655b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation = null; 65676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 657b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 658b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 659b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 660b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final AnimatorSet stateAnimation = mStateAnimation; 661b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Runnable startAnimRunnable = new Runnable() { 662b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void run() { 663b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Check that mStateAnimation hasn't changed while 664b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // we waited for a layout/draw pass 665b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (mStateAnimation != stateAnimation) 666b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return; 667b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 668b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 669b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 670b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Enable all necessary layers 67111509ad61afb7424ce83057b0d2a4b09f853651fWinson Chung boolean isLmpOrAbove = Utilities.isLmpOrAbove(); 672b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 673b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 674b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 675b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 67611509ad61afb7424ce83057b0d2a4b09f853651fWinson Chung if (isLmpOrAbove && Utilities.isViewAttachedToWindow(v)) { 677b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.buildLayer(); 678b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 679b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 680b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.start(); 681b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 682b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 683b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.post(startAnimRunnable); 684b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 685b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.setVisibility(View.GONE); 686b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, true); 687b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, true); 688b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, true); 689b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, true); 690b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, true); 691b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, true); 69276648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 693b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 694b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Run any queued runnables 695b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (onCompleteRunnable != null) { 696b745afbdd75157c73d581b345118cdaff99e912dWinson Chung onCompleteRunnable.run(); 697b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 698b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 699b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 700b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 701b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 702b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 703b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the prepare-transition event to suitable views. 704b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 705b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) { 706b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 707b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated, 708b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 709b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 710b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 711b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 712b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 713b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the start-transition event to suitable views. 714b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 715b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) { 716b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 717b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated, 718b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 719b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 720b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 721b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Update the workspace transition step as well 722b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStep(v, 0f); 723b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 724b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 725b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 726b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the step-transition event to suitable views. 727b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 728b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionStep(View v, float t) { 729b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 730b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t); 731b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 732b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 733b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 734b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the end-transition event to suitable views. 736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) { 738b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 739b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated, 740b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 742b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 743b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Update the workspace transition step as well 744b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStep(v, 1f); 745b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 746b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 747b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 748b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Cancels the current animation. 749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 750b745afbdd75157c73d581b345118cdaff99e912dWinson Chung private void cancelAnimation() { 751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (mStateAnimation != null) { 752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.setDuration(0); 753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation.cancel(); 754b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mStateAnimation = null; 755b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 756b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 7571558893b873cd55b2df779f594f1de3c370d3328Adam Cohen} 758