LauncherStateTransitionAnimation.java revision 3f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3
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; 250bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickhamimport android.animation.ValueAnimator; 267066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyalimport android.annotation.SuppressLint; 27756cd26592dee6b956becdc24d60995c64de9153Sunny Goyalimport android.annotation.TargetApi; 28b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.content.res.Resources; 29756cd26592dee6b956becdc24d60995c64de9153Sunny Goyalimport android.os.Build; 30b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.util.Log; 31b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.View; 32b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.AccelerateInterpolator; 33b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.DecelerateInterpolator; 341558893b873cd55b2df779f594f1de3c370d3328Adam Cohen 355f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chungimport com.android.launcher3.allapps.AllAppsContainerView; 36091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 375d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyalimport com.android.launcher3.util.UiThreadCircularReveal; 383f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport com.android.launcher3.widget.WidgetsContainerView; 391558893b873cd55b2df779f594f1de3c370d3328Adam Cohen 40b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport java.util.HashMap; 41b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 42b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/** 43b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * TODO: figure out what kind of tests we can write for this 44b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * 45b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Things to test when changing the following class. 46b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Home from workspace 47b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from center screen 48b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from other screens 49b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Home from all apps 50b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from center screen 51b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from other screens 52b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Back from all apps 53b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from center screen 54b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from other screens 55b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Launch app from workspace and quit 56b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 57b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 58b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Launch app from all apps and quit 59b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 60b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 61b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Go to a screen that's not the default, then all 62b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * apps, and launch and app, and go back 63b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 64b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * -with home 65b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On workspace, long press power and go back 66b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 67b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 68b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On all apps, long press power and go back 69b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 70b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 71b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On workspace, power off 72b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On all apps, power off 73b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Launch an app and turn off the screen while in that app 74b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Go back with home key 75b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Go back with back key TODO: make this not go to workspace 76b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From all apps 77b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From workspace 78b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Enter and exit car mode (becuase it causes an extra configuration changed) 79b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From all apps 80b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From the center workspace 81b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From another workspace 82b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 83b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpublic class LauncherStateTransitionAnimation { 84b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 850ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private static final float FINAL_REVEAL_ALPHA_FOR_WIDGETS = 0.3f; 860ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 87b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 88b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Private callbacks made during transition setup. 89b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 900ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private static class PrivateTransitionCallbacks { 910ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private final float materialRevealViewFinalAlpha; 920ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 930ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks(float revealAlpha) { 940ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal materialRevealViewFinalAlpha = revealAlpha; 95b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 960ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 97b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewStartFinalRadius() { 98b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return 0; 99b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 100b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(View revealView, 10198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song View buttonView) { 102b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return null; 103b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 10476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung void onTransitionComplete() {} 105b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 106b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1070ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal public static final String TAG = "LSTAnimation"; 108b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 109b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Flags to determine how to set the layers on views before the transition animation 110b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public static final int BUILD_LAYER = 0; 111b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public static final int BUILD_AND_SET_LAYER = 1; 112b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public static final int SINGLE_FRAME_DELAY = 16; 113b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 114091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk Launcher mLauncher; 115006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung @Thunk AnimatorSet mCurrentAnimation; 116b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 117006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung public LauncherStateTransitionAnimation(Launcher l) { 118b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mLauncher = l; 119b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 120b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 121b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 122b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts an animation to the apps view. 12376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * 12476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * @param startSearchAfterTransition Immediately starts app search after the transition to 12576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * All Apps is completed. 126b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 127006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung public void startAnimationToAllApps(final Workspace.State fromWorkspaceState, 128006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final boolean animated, final boolean startSearchAfterTransition) { 1295f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final AllAppsContainerView toView = mLauncher.getAppsView(); 13098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View buttonView = mLauncher.getAllAppsButton(); 1310ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) { 132b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 133b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public float getMaterialRevealViewStartFinalRadius() { 1342e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; 135b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return allAppsButtonSize / 2; 136b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 137b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 138b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 139b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View revealView, final View allAppsButtonView) { 140b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 141b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationStart(Animator animation) { 142b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.INVISIBLE); 143b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 144b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 145b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.VISIBLE); 146b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 147b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 148b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 14976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung @Override 15076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung void onTransitionComplete() { 1518fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song mLauncher.getLogger().resetElapsedContainerMillis(); 15276648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung if (startSearchAfterTransition) { 15376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung toView.startAppsSearch(); 15476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung } 15576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung } 156b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 157ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating from spring loaded mode back to all apps 158006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState, 1590ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal Workspace.State.NORMAL_HIDDEN, buttonView, toView, animated, cb); 160b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 161b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 162b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 163b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts an animation to the widgets view. 164b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 165006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung public void startAnimationToWidgets(final Workspace.State fromWorkspaceState, 166006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final boolean animated) { 1673f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song final WidgetsContainerView toView = mLauncher.getWidgetsView(); 16898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View buttonView = mLauncher.getWidgetsButton(); 169006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState, 1700ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal Workspace.State.OVERVIEW_HIDDEN, buttonView, toView, animated, 1718fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS){ 1728fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 1738fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 1748fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song mLauncher.getLogger().resetElapsedContainerMillis(); 1758fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 1768fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song }); 177b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 178b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 179b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 1806d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the current overlay view. 181b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 182b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void startAnimationToWorkspace(final Launcher.State fromState, 183006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 1842a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final boolean animated, final Runnable onCompleteRunnable) { 185b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (toWorkspaceState != Workspace.State.NORMAL && 186b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspaceState != Workspace.State.SPRING_LOADED && 187b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspaceState != Workspace.State.OVERVIEW) { 188b745afbdd75157c73d581b345118cdaff99e912dWinson Chung Log.e(TAG, "Unexpected call to startAnimationToWorkspace"); 189b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 190b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 191b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED) { 1922a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson startAnimationToWorkspaceFromAllApps(fromWorkspaceState, toWorkspaceState, 193dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung animated, onCompleteRunnable); 1946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else if (fromState == Launcher.State.WIDGETS || 1956d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham fromState == Launcher.State.WIDGETS_SPRING_LOADED) { 1962a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson startAnimationToWorkspaceFromWidgets(fromWorkspaceState, toWorkspaceState, 197dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung animated, onCompleteRunnable); 1986d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else { 1996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham startAnimationToNewWorkspaceState(fromWorkspaceState, toWorkspaceState, 2006d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham animated, onCompleteRunnable); 201b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 202b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 203b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 204b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 205b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to a particular overlay view. 206b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 2077066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal @SuppressLint("NewApi") 2080ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private AnimatorSet startAnimationToOverlay( 2090ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 2100ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View buttonView, final BaseContainerView toView, 211006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final boolean animated, final PrivateTransitionCallbacks pCb) { 212006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 213b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 2149fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal final boolean material = Utilities.ATLEAST_LOLLIPOP; 2155f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 2160ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final int itemsAlphaStagger = res.getInteger(R.integer.config_overlayItemsAlphaStagger); 217b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 218b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View fromView = mLauncher.getWorkspace(); 219b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 220b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final HashMap<View, Integer> layerViews = new HashMap<>(); 221b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 222b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 22398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 224b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 225b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 226b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 227b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 2287c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal playCommonTransitionAnimations(toWorkspaceState, fromView, toView, 2297c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal animated, initialized, animation, revealDuration, layerViews); 2300bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 2310ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View contentView = toView.getContentView(); 2320bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 233006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (animated && initialized) { 234b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the reveal view animation 2350ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View revealView = toView.getRevealView(); 2360ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 237b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 238b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 239f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 240b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 241b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(0f); 242b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0f); 243b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationX(0f); 244b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 245b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 246b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha; 247b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 248b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 249b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 2500ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace( 2510ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal revealView, buttonView, null); 2520ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal revealViewToAlpha = pCb.materialRevealViewFinalAlpha; 25398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 25498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 255b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 256b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToAlpha = 0f; 257b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 258b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 259b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 260b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 261b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the animators 262b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelAlpha = 2635d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f); 264b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftY = 2655d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0); 266b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftX = 2675d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0); 268b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView, 269b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha, panelDriftY, panelDriftX); 270b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setDuration(revealDuration); 271b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 272b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 273b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Play the animation 274b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(revealView, BUILD_AND_SET_LAYER); 275006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlphaAndDrift); 276b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 277b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 278b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setVisibility(View.VISIBLE); 279b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(0f); 280b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(revealViewToYDrift); 281b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(contentView, BUILD_AND_SET_LAYER); 282b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 283b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 284b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 285b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift, 0); 286b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration); 287b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger); 289006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f); 292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(revealDuration); 293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 294b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setStartDelay(itemsAlphaStagger); 295006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 297b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 298b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float startRadius = pCb.getMaterialRevealViewStartFinalRadius(); 299b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener( 30098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealView, buttonView); 3011558893b873cd55b2df779f594f1de3c370d3328Adam Cohen Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2, 302b745afbdd75157c73d581b345118cdaff99e912dWinson Chung height / 2, startRadius, revealRadius); 303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 305b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 308006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(reveal); 309b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 311006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 312b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 313b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 314b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, false); 315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, false); 316b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Disable all necessary layers 321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 322b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 323b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_NONE, null); 324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 328006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 32976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Dispatch the prepare transition signal 335b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, false); 336b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, false); 337b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 338006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet stateAnimation = animation; 339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Runnable startAnimRunnable = new Runnable() { 340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void run() { 341006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Check that mCurrentAnimation hasn't changed while 342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // we waited for a layout/draw pass 343006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != stateAnimation) 344b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return; 345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 347b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 348b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Enable all necessary layers 349b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 350b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 353756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 354b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.buildLayer(); 355b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 357b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Focus the new view 359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.requestFocus(); 360b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 361006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung stateAnimation.start(); 362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.bringToFront(); 365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setVisibility(View.VISIBLE); 366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.post(startAnimRunnable); 367006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 368006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung return animation; 369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setTranslationX(0.0f); 371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setTranslationY(0.0f); 372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setScaleX(1.0f); 373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setScaleY(1.0f); 374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setVisibility(View.VISIBLE); 375b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.bringToFront(); 376b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 377b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Show the content view 378b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setVisibility(View.VISIBLE); 379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 380b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, false); 381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, false); 383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, false); 384b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, false); 38676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 387006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 388006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung return null; 389b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 390b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 391b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 392b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 393685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham * Plays animations used by various transitions. 394685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham */ 3957c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal private void playCommonTransitionAnimations( 3967c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal Workspace.State toWorkspaceState, View fromView, View toView, 397685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham boolean animated, boolean initialized, AnimatorSet animation, int revealDuration, 398685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham HashMap<View, Integer> layerViews) { 399685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Create the workspace animation. 400685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // NOTE: this call apparently also sets the state for the workspace if !animated 401685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState, 402685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animated, layerViews); 403685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 404685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Animate the search bar 4057c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal final SearchDropTargetBar.State toSearchBarState = 4062e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal toWorkspaceState.searchDropTargetBarState; 4077c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState, 4087c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal animated ? revealDuration : 0, animation); 409685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 410685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham if (animated && initialized) { 411685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Play the workspace animation 412685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham if (workspaceAnim != null) { 413685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animation.play(workspaceAnim); 414685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 415685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Dispatch onLauncherTransitionStep() as the animation interpolates. 416685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animation.play(dispatchOnLauncherTransitionStepAnim(fromView, toView)); 417685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 418685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 419685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 420685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham /** 4210bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * Returns an Animator that calls {@link #dispatchOnLauncherTransitionStep(View, float)} on 4220bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * {@param fromView} and {@param toView} as the animation interpolates. 4230bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * 4240bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * This is a bit hacky: we create a dummy ValueAnimator just for the AnimatorUpdateListener. 4250bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham */ 4260bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham private Animator dispatchOnLauncherTransitionStepAnim(final View fromView, final View toView) { 4270bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham ValueAnimator updateAnimator = ValueAnimator.ofFloat(0, 1); 4280bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham updateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 4290bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham @Override 4300bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham public void onAnimationUpdate(ValueAnimator animation) { 4310bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham dispatchOnLauncherTransitionStep(fromView, animation.getAnimatedFraction()); 4320bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham dispatchOnLauncherTransitionStep(toView, animation.getAnimatedFraction()); 4330bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham } 4340bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham }); 4350bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham return updateAnimator; 4360bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham } 4370bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 4380bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham /** 4396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the apps view. 440b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 441006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState, 4422a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Workspace.State toWorkspaceState, final boolean animated, 4432a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 4445f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung AllAppsContainerView appsView = mLauncher.getAppsView(); 4450ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal // No alpha anim from all apps 4460ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) { 447b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 448b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewStartFinalRadius() { 4492e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; 450b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return allAppsButtonSize / 2; 451b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 452b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 453b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 454b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View revealView, final View allAppsButtonView) { 455b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 456b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationStart(Animator animation) { 457b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // We set the alpha instead of visibility to ensure that the focus does not 458b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // get taken from the all apps view 459b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.VISIBLE); 460b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(0f); 461b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 462b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 463b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 464b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 465b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 466b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Show the all apps button, and focus it 467b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(1f); 468b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 469b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 470b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 4718fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 4728fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 4738fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song mLauncher.getLogger().resetElapsedContainerMillis(); 4748fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 475b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 476ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating to spring loaded mode from all apps 477006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState, 4787c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal mLauncher.getAllAppsButton(), appsView, 4790ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal animated, onCompleteRunnable, cb); 480b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 481b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 482b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 4836d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the widgets view. 484b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 485006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState, 4866d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Workspace.State toWorkspaceState, final boolean animated, 4872a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 4884cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song final WidgetsContainerView widgetsView = mLauncher.getWidgetsView(); 4890ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = 4900ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS) { 491b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 492b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 49398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View revealView, final View widgetsButtonView) { 494b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 495b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 496b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 497b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 498b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 499b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 500b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 5018fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 5028fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 5038fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song mLauncher.getLogger().resetElapsedContainerMillis(); 5048fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 505b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 5060ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal mCurrentAnimation = startAnimationToWorkspaceFromOverlay( 5070ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal fromWorkspaceState, toWorkspaceState, 5087c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal mLauncher.getWidgetsButton(), widgetsView, 5090ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal animated, onCompleteRunnable, cb); 510b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 511b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 512b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 5136d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from another workspace state, e.g. normal to overview. 5146d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham */ 5156d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham private void startAnimationToNewWorkspaceState(final Workspace.State fromWorkspaceState, 5166d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Workspace.State toWorkspaceState, final boolean animated, 5176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Runnable onCompleteRunnable) { 5186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final View fromWorkspace = mLauncher.getWorkspace(); 5196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final HashMap<View, Integer> layerViews = new HashMap<>(); 5206d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 5216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final int revealDuration = mLauncher.getResources() 5226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham .getInteger(R.integer.config_overlayRevealTime); 5236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5246d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Cancel the current animation 5256d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham cancelAnimation(); 5266d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5277c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal playCommonTransitionAnimations(toWorkspaceState, fromWorkspace, null, 5287c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal animated, animated, animation, revealDuration, layerViews); 5296d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5306d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (animated) { 5316d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, true); 5326d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5336d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final AnimatorSet stateAnimation = animation; 5346d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Runnable startAnimRunnable = new Runnable() { 5356d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham @TargetApi(Build.VERSION_CODES.LOLLIPOP) 5366d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham public void run() { 5376d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Check that mCurrentAnimation hasn't changed while 5386d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // we waited for a layout/draw pass 5396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (mCurrentAnimation != stateAnimation) 5406d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham return; 5416d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5426d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionStart(fromWorkspace, animated, true); 5436d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5446d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Enable all necessary layers 5456d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham for (View v : layerViews.keySet()) { 5466d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 5476d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 5486d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5496d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 5506d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.buildLayer(); 5516d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5526d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5536d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham stateAnimation.start(); 5546d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5556d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham }; 5566d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham animation.addListener(new AnimatorListenerAdapter() { 5576d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham @Override 5586d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham public void onAnimationEnd(Animator animation) { 5596d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true); 5606d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5616d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Run any queued runnables 5626d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (onCompleteRunnable != null) { 5636d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham onCompleteRunnable.run(); 5646d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5656d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5666d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Disable all necessary layers 5676d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham for (View v : layerViews.keySet()) { 5686d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 5696d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.setLayerType(View.LAYER_TYPE_NONE, null); 5706d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5716d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5726d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5736d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // This can hold unnecessary references to views. 5746d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham cleanupAnimation(); 5756d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5766d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham }); 5776d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham fromWorkspace.post(startAnimRunnable); 5786d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham mCurrentAnimation = animation; 5796d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else /* if (!animated) */ { 5806d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, true); 5816d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionStart(fromWorkspace, animated, true); 5826d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true); 5836d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5846d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Run any queued runnables 5856d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (onCompleteRunnable != null) { 5866d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham onCompleteRunnable.run(); 5876d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5886d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5896d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham mCurrentAnimation = null; 5906d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5916d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5926d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5936d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham /** 594b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to the workspace. 595b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 5960ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private AnimatorSet startAnimationToWorkspaceFromOverlay( 5970ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 5980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View buttonView, final BaseContainerView fromView, 5990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final boolean animated, final Runnable onCompleteRunnable, 600006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final PrivateTransitionCallbacks pCb) { 601006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 602b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 6039fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal final boolean material = Utilities.ATLEAST_LOLLIPOP; 6045f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 605b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final int itemsAlphaStagger = 6065f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung res.getInteger(R.integer.config_overlayItemsAlphaStagger); 607b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 608b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View toView = mLauncher.getWorkspace(); 609b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 610b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final HashMap<View, Integer> layerViews = new HashMap<>(); 611b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 612b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 61398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 614b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 615b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 616b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 617b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 6187c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal playCommonTransitionAnimations(toWorkspaceState, fromView, toView, 6197c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal animated, initialized, animation, revealDuration, layerViews); 6200bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 621006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (animated && initialized) { 6220ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View revealView = fromView.getRevealView(); 6230ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View contentView = fromView.getContentView(); 6240bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 625b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // hideAppsCustomizeHelper is called in some cases when it is already hidden 626b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // don't perform all these no-op animations. In particularly, this was causing 627b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // the all-apps button to pop in and out. 628b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (fromView.getVisibility() == View.VISIBLE) { 629b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 630b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 631f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 632b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 633b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(1f); 634b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0); 635b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(revealView, BUILD_AND_SET_LAYER); 636b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 637b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 638b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 639b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 640b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 64198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, 64298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song buttonView, null); 64398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 64498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 645b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 646b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 647b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 648b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 649b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 650b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // The vertical motion of the apps panel should be delayed by one frame 651b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // from the conceal animation in order to give the right feel. We correspondingly 652b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // shorten the duration so that the slide and conceal end at the same time. 653b745afbdd75157c73d581b345118cdaff99e912dWinson Chung TimeInterpolator decelerateInterpolator = material ? 654b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new LogDecelerateInterpolator(100, 0) : 655b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new DecelerateInterpolator(1f); 6561558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY", 657b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 658b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY); 659b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 660b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setInterpolator(decelerateInterpolator); 661006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftY); 662b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 6631558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX", 664b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToXDrift); 665b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY); 666b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 667b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setInterpolator(decelerateInterpolator); 668006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftX); 669b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 670b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup animation for the reveal panel alpha 671b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha = !material ? 0f : 6720ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal pCb.materialRevealViewFinalAlpha; 673b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (revealViewToAlpha != 1f) { 6741558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha", 675b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1f, revealViewToAlpha); 676b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setDuration(material ? revealDuration : 150); 677b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY); 678b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setInterpolator(decelerateInterpolator); 679006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlpha); 680b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 681b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 682b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 683b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(contentView, BUILD_AND_SET_LAYER); 684b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 685b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 6861558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 687b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 688b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 689b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY); 690b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(decelerateInterpolator); 691b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 692006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 693b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 694b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1f); 6951558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f); 696b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(100); 697b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(decelerateInterpolator); 698006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 699b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 7003f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham // Invalidate the scrim throughout the animation to ensure the highlight 7013f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham // cutout is correct throughout. 7023f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham ValueAnimator invalidateScrim = ValueAnimator.ofFloat(0f, 1f); 7033f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham invalidateScrim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 7043f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham @Override 7053f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham public void onAnimationUpdate(ValueAnimator animation) { 7063f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham mLauncher.getDragLayer().invalidateScrim(); 7073f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham } 7083f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham }); 7093f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham animation.play(invalidateScrim); 7103f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham 711b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 712b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Animate the all apps button 713b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float finalRadius = pCb.getMaterialRevealViewStartFinalRadius(); 714b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = 71598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView); 7161558893b873cd55b2df779f594f1de3c370d3328Adam Cohen Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2, 7171558893b873cd55b2df779f594f1de3c370d3328Adam Cohen height / 2, revealRadius, finalRadius); 718b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 719b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 720b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setStartDelay(itemsAlphaStagger); 721b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 722b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 723b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 724006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(reveal); 725b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 726b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 727b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 728a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham dispatchOnLauncherTransitionPrepare(fromView, animated, true); 729a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham dispatchOnLauncherTransitionPrepare(toView, animated, true); 730a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham 731006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 732b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 733b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 734b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.setVisibility(View.GONE); 735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, true); 736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, true); 737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 738b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Run any queued runnables 739b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (onCompleteRunnable != null) { 740b745afbdd75157c73d581b345118cdaff99e912dWinson Chung onCompleteRunnable.run(); 741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 742b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 743b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Disable all necessary layers 744b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 745b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 746b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_NONE, null); 747b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 748b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 750b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Reset page transforms 751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (contentView != null) { 752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationX(0); 753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 754b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1); 755b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 756b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 758006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 75976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 760b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 761b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 762b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 763006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet stateAnimation = animation; 764b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Runnable startAnimRunnable = new Runnable() { 765756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal @TargetApi(Build.VERSION_CODES.LOLLIPOP) 766b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void run() { 767006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Check that mCurrentAnimation hasn't changed while 768b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // we waited for a layout/draw pass 769006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != stateAnimation) 770b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return; 771006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 772b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 773b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 774b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 775b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Enable all necessary layers 776b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 777b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 778b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 779b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 780756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 781b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.buildLayer(); 782b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 783b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 784006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung stateAnimation.start(); 785b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 786b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 787b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.post(startAnimRunnable); 788006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 789006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung return animation; 7906d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else /* if (!(animated && initialized)) */ { 791b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.setVisibility(View.GONE); 792b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, true); 793b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, true); 794b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, true); 795b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, true); 796b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, true); 797b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, true); 79876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 799b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 800b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Run any queued runnables 801b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (onCompleteRunnable != null) { 802b745afbdd75157c73d581b345118cdaff99e912dWinson Chung onCompleteRunnable.run(); 803b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 804006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 805006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung return null; 806b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 807b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 808b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 809006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung /** 810b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the prepare-transition event to suitable views. 811b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 812b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) { 813b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 814b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated, 815b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 816b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 817b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 818b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 819b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 820b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the start-transition event to suitable views. 821b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 822b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) { 823b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 824b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated, 825b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 826b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 827b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 828b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Update the workspace transition step as well 829b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStep(v, 0f); 830b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 831b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 832b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 833b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the step-transition event to suitable views. 834b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 835b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionStep(View v, float t) { 836b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 837b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t); 838b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 839b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 840b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 841b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 842b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the end-transition event to suitable views. 843b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 844b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) { 845b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 846b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated, 847b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 848b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 849b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 850b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Update the workspace transition step as well 851b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStep(v, 1f); 852b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 853b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 854b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 855b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Cancels the current animation. 856b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 857b745afbdd75157c73d581b345118cdaff99e912dWinson Chung private void cancelAnimation() { 858006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != null) { 859006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.setDuration(0); 860006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.cancel(); 861006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 862b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 863b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 864006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 865d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal @Thunk void cleanupAnimation() { 866006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 867006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung } 8681558893b873cd55b2df779f594f1de3c370d3328Adam Cohen} 869