LauncherStateTransitionAnimation.java revision 7c50b31f57e3e3ec1f433d243afe05554dcaf977
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() { 15176648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung if (startSearchAfterTransition) { 15276648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung toView.startAppsSearch(); 15376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung } 15476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung } 155b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 156ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating from spring loaded mode back to all apps 157006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState, 1580ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal Workspace.State.NORMAL_HIDDEN, buttonView, toView, animated, cb); 159b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 160b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 161b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 162b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts an animation to the widgets view. 163b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 164006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung public void startAnimationToWidgets(final Workspace.State fromWorkspaceState, 165006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final boolean animated) { 1663f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song final WidgetsContainerView toView = mLauncher.getWidgetsView(); 16798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View buttonView = mLauncher.getWidgetsButton(); 168006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState, 1690ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal Workspace.State.OVERVIEW_HIDDEN, buttonView, toView, animated, 1700ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS)); 171b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 172b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 173b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 1746d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the current overlay view. 175b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 176b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void startAnimationToWorkspace(final Launcher.State fromState, 177006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 1782a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final boolean animated, final Runnable onCompleteRunnable) { 179b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (toWorkspaceState != Workspace.State.NORMAL && 180b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspaceState != Workspace.State.SPRING_LOADED && 181b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspaceState != Workspace.State.OVERVIEW) { 182b745afbdd75157c73d581b345118cdaff99e912dWinson Chung Log.e(TAG, "Unexpected call to startAnimationToWorkspace"); 183b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 184b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 185b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED) { 1862a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson startAnimationToWorkspaceFromAllApps(fromWorkspaceState, toWorkspaceState, 187dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung animated, onCompleteRunnable); 1886d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else if (fromState == Launcher.State.WIDGETS || 1896d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham fromState == Launcher.State.WIDGETS_SPRING_LOADED) { 1902a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson startAnimationToWorkspaceFromWidgets(fromWorkspaceState, toWorkspaceState, 191dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung animated, onCompleteRunnable); 1926d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else { 1936d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham startAnimationToNewWorkspaceState(fromWorkspaceState, toWorkspaceState, 1946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham animated, onCompleteRunnable); 195b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 196b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 197b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 198b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 199b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to a particular overlay view. 200b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 2017066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal @SuppressLint("NewApi") 2020ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private AnimatorSet startAnimationToOverlay( 2030ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 2040ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View buttonView, final BaseContainerView toView, 205006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final boolean animated, final PrivateTransitionCallbacks pCb) { 206006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 207b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 2089fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal final boolean material = Utilities.ATLEAST_LOLLIPOP; 2095f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 2100ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final int itemsAlphaStagger = res.getInteger(R.integer.config_overlayItemsAlphaStagger); 211b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 212b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View fromView = mLauncher.getWorkspace(); 213b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 214b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final HashMap<View, Integer> layerViews = new HashMap<>(); 215b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 216b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 21798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 218b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 219b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 220b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 221b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 2227c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal playCommonTransitionAnimations(toWorkspaceState, fromView, toView, 2237c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal animated, initialized, animation, revealDuration, layerViews); 2240bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 2250ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View contentView = toView.getContentView(); 2260bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 227006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (animated && initialized) { 228b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the reveal view animation 2290ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View revealView = toView.getRevealView(); 2300ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 231b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 232b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 233f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 234b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 235b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(0f); 236b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0f); 237b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationX(0f); 238b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 239b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 240b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha; 241b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 242b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 243b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 2440ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace( 2450ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal revealView, buttonView, null); 2460ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal revealViewToAlpha = pCb.materialRevealViewFinalAlpha; 24798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 24898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 249b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 250b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToAlpha = 0f; 251b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 252b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 253b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 254b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 255b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the animators 256b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelAlpha = 2575d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f); 258b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftY = 2595d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0); 260b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftX = 2615d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0); 262b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView, 263b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha, panelDriftY, panelDriftX); 264b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setDuration(revealDuration); 265b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 266b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 267b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Play the animation 268b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(revealView, BUILD_AND_SET_LAYER); 269006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlphaAndDrift); 270b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 271b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 272b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setVisibility(View.VISIBLE); 273b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(0f); 274b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(revealViewToYDrift); 275b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(contentView, BUILD_AND_SET_LAYER); 276b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 277b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 278b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 279b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift, 0); 280b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration); 281b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 282b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger); 283006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 284b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 285b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f); 286b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(revealDuration); 287b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setStartDelay(itemsAlphaStagger); 289006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float startRadius = pCb.getMaterialRevealViewStartFinalRadius(); 293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener( 29498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealView, buttonView); 2951558893b873cd55b2df779f594f1de3c370d3328Adam Cohen Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2, 296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung height / 2, startRadius, revealRadius); 297b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 298b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 299b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 300b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 301b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 302006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(reveal); 303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 305006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 308b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, false); 309b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, false); 310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 311b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 312b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 313b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 314b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Disable all necessary layers 315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 316b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_NONE, null); 318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 322006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 32376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 328b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Dispatch the prepare transition signal 329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, false); 330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, false); 331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 332006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet stateAnimation = animation; 333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Runnable startAnimRunnable = new Runnable() { 334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void run() { 335006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Check that mCurrentAnimation hasn't changed while 336b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // we waited for a layout/draw pass 337006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != stateAnimation) 338b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return; 339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 341b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Enable all necessary layers 343b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 344b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 347756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 348b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.buildLayer(); 349b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 350b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Focus the new view 353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.requestFocus(); 354b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 355006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung stateAnimation.start(); 356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 357b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.bringToFront(); 359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setVisibility(View.VISIBLE); 360b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.post(startAnimRunnable); 361006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 362006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung return animation; 363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setTranslationX(0.0f); 365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setTranslationY(0.0f); 366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setScaleX(1.0f); 367b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setScaleY(1.0f); 368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setVisibility(View.VISIBLE); 369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.bringToFront(); 370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Show the content view 372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setVisibility(View.VISIBLE); 373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, false); 375b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 376b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, false); 377b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, false); 378b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, false); 38076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 381006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 382006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung return null; 383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 384b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 386b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 387685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham * Plays animations used by various transitions. 388685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham */ 3897c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal private void playCommonTransitionAnimations( 3907c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal Workspace.State toWorkspaceState, View fromView, View toView, 391685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham boolean animated, boolean initialized, AnimatorSet animation, int revealDuration, 392685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham HashMap<View, Integer> layerViews) { 393685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Create the workspace animation. 394685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // NOTE: this call apparently also sets the state for the workspace if !animated 395685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState, 396685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animated, layerViews); 397685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 398685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Animate the search bar 3997c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal final SearchDropTargetBar.State toSearchBarState = 4007c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal toWorkspaceState.getSearchDropTargetBarState(); 4017c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState, 4027c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal animated ? revealDuration : 0, animation); 403685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 404685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham if (animated && initialized) { 405685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Play the workspace animation 406685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham if (workspaceAnim != null) { 407685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animation.play(workspaceAnim); 408685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 409685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Dispatch onLauncherTransitionStep() as the animation interpolates. 410685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animation.play(dispatchOnLauncherTransitionStepAnim(fromView, toView)); 411685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 412685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 413685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 414685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham /** 4150bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * Returns an Animator that calls {@link #dispatchOnLauncherTransitionStep(View, float)} on 4160bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * {@param fromView} and {@param toView} as the animation interpolates. 4170bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * 4180bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * This is a bit hacky: we create a dummy ValueAnimator just for the AnimatorUpdateListener. 4190bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham */ 4200bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham private Animator dispatchOnLauncherTransitionStepAnim(final View fromView, final View toView) { 4210bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham ValueAnimator updateAnimator = ValueAnimator.ofFloat(0, 1); 4220bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham updateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 4230bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham @Override 4240bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham public void onAnimationUpdate(ValueAnimator animation) { 4250bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham dispatchOnLauncherTransitionStep(fromView, animation.getAnimatedFraction()); 4260bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham dispatchOnLauncherTransitionStep(toView, animation.getAnimatedFraction()); 4270bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham } 4280bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham }); 4290bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham return updateAnimator; 4300bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham } 4310bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 4320bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham /** 4336d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the apps view. 434b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 435006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState, 4362a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Workspace.State toWorkspaceState, final boolean animated, 4372a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 4385f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung AllAppsContainerView appsView = mLauncher.getAppsView(); 4390ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal // No alpha anim from all apps 4400ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) { 441b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 442b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewStartFinalRadius() { 4432e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; 444b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return allAppsButtonSize / 2; 445b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 446b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 447b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 448b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View revealView, final View allAppsButtonView) { 449b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 450b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationStart(Animator animation) { 451b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // We set the alpha instead of visibility to ensure that the focus does not 452b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // get taken from the all apps view 453b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.VISIBLE); 454b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(0f); 455b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 456b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 457b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 458b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 459b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 460b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Show the all apps button, and focus it 461b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(1f); 462b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 463b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 464b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 465b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 466ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating to spring loaded mode from all apps 467006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState, 4687c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal mLauncher.getAllAppsButton(), appsView, 4690ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal animated, onCompleteRunnable, cb); 470b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 471b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 472b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 4736d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the widgets view. 474b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 475006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState, 4766d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Workspace.State toWorkspaceState, final boolean animated, 4772a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 4784cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song final WidgetsContainerView widgetsView = mLauncher.getWidgetsView(); 4790ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = 4800ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS) { 481b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 482b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 48398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View revealView, final View widgetsButtonView) { 484b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 485b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 486b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 487b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 488b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 489b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 490b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 491b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 4920ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal mCurrentAnimation = startAnimationToWorkspaceFromOverlay( 4930ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal fromWorkspaceState, toWorkspaceState, 4947c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal mLauncher.getWidgetsButton(), widgetsView, 4950ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal animated, onCompleteRunnable, cb); 496b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 497b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 498b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 4996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from another workspace state, e.g. normal to overview. 5006d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham */ 5016d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham private void startAnimationToNewWorkspaceState(final Workspace.State fromWorkspaceState, 5026d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Workspace.State toWorkspaceState, final boolean animated, 5036d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Runnable onCompleteRunnable) { 5046d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final View fromWorkspace = mLauncher.getWorkspace(); 5056d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final HashMap<View, Integer> layerViews = new HashMap<>(); 5066d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 5076d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final int revealDuration = mLauncher.getResources() 5086d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham .getInteger(R.integer.config_overlayRevealTime); 5096d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5106d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Cancel the current animation 5116d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham cancelAnimation(); 5126d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5137c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal playCommonTransitionAnimations(toWorkspaceState, fromWorkspace, null, 5147c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal animated, animated, animation, revealDuration, layerViews); 5156d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5166d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (animated) { 5176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, true); 5186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final AnimatorSet stateAnimation = animation; 5206d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Runnable startAnimRunnable = new Runnable() { 5216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham @TargetApi(Build.VERSION_CODES.LOLLIPOP) 5226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham public void run() { 5236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Check that mCurrentAnimation hasn't changed while 5246d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // we waited for a layout/draw pass 5256d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (mCurrentAnimation != stateAnimation) 5266d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham return; 5276d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5286d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionStart(fromWorkspace, animated, true); 5296d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5306d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Enable all necessary layers 5316d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham for (View v : layerViews.keySet()) { 5326d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 5336d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 5346d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5356d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 5366d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.buildLayer(); 5376d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5386d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham stateAnimation.start(); 5406d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5416d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham }; 5426d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham animation.addListener(new AnimatorListenerAdapter() { 5436d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham @Override 5446d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham public void onAnimationEnd(Animator animation) { 5456d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true); 5466d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5476d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Run any queued runnables 5486d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (onCompleteRunnable != null) { 5496d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham onCompleteRunnable.run(); 5506d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5516d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5526d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Disable all necessary layers 5536d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham for (View v : layerViews.keySet()) { 5546d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 5556d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.setLayerType(View.LAYER_TYPE_NONE, null); 5566d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5576d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5586d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5596d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // This can hold unnecessary references to views. 5606d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham cleanupAnimation(); 5616d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5626d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham }); 5636d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham fromWorkspace.post(startAnimRunnable); 5646d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham mCurrentAnimation = animation; 5656d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else /* if (!animated) */ { 5666d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, true); 5676d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionStart(fromWorkspace, animated, true); 5686d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true); 5696d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5706d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Run any queued runnables 5716d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (onCompleteRunnable != null) { 5726d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham onCompleteRunnable.run(); 5736d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5746d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5756d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham mCurrentAnimation = null; 5766d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5776d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5786d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5796d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham /** 580b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to the workspace. 581b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 5820ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private AnimatorSet startAnimationToWorkspaceFromOverlay( 5830ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 5840ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View buttonView, final BaseContainerView fromView, 5850ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final boolean animated, final Runnable onCompleteRunnable, 586006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final PrivateTransitionCallbacks pCb) { 587006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 588b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 5899fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal final boolean material = Utilities.ATLEAST_LOLLIPOP; 5905f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 591b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final int itemsAlphaStagger = 5925f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung res.getInteger(R.integer.config_overlayItemsAlphaStagger); 593b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 594b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View toView = mLauncher.getWorkspace(); 595b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 596b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final HashMap<View, Integer> layerViews = new HashMap<>(); 597b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 598b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 59998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 600b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 601b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 602b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 603b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 6047c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal playCommonTransitionAnimations(toWorkspaceState, fromView, toView, 6057c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal animated, initialized, animation, revealDuration, layerViews); 6060bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 607006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (animated && initialized) { 6080ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View revealView = fromView.getRevealView(); 6090ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View contentView = fromView.getContentView(); 6100bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 611b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // hideAppsCustomizeHelper is called in some cases when it is already hidden 612b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // don't perform all these no-op animations. In particularly, this was causing 613b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // the all-apps button to pop in and out. 614b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (fromView.getVisibility() == View.VISIBLE) { 615b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 616b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 617f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 618b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 619b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(1f); 620b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0); 621b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(revealView, BUILD_AND_SET_LAYER); 622b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 623b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 624b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 625b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 626b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 62798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, 62898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song buttonView, null); 62998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 63098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 631b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 632b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 633b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 634b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 635b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 636b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // The vertical motion of the apps panel should be delayed by one frame 637b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // from the conceal animation in order to give the right feel. We correspondingly 638b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // shorten the duration so that the slide and conceal end at the same time. 639b745afbdd75157c73d581b345118cdaff99e912dWinson Chung TimeInterpolator decelerateInterpolator = material ? 640b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new LogDecelerateInterpolator(100, 0) : 641b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new DecelerateInterpolator(1f); 6421558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY", 643b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 644b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY); 645b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 646b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setInterpolator(decelerateInterpolator); 647006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftY); 648b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 6491558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX", 650b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToXDrift); 651b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY); 652b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 653b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setInterpolator(decelerateInterpolator); 654006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftX); 655b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 656b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup animation for the reveal panel alpha 657b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha = !material ? 0f : 6580ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal pCb.materialRevealViewFinalAlpha; 659b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (revealViewToAlpha != 1f) { 6601558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha", 661b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1f, revealViewToAlpha); 662b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setDuration(material ? revealDuration : 150); 663b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY); 664b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setInterpolator(decelerateInterpolator); 665006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlpha); 666b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 667b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 668b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 669b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(contentView, BUILD_AND_SET_LAYER); 670b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 671b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 6721558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 673b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 674b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 675b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY); 676b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(decelerateInterpolator); 677b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 678006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 679b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 680b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1f); 6811558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f); 682b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(100); 683b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(decelerateInterpolator); 684006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 685b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 686b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 687b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Animate the all apps button 688b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float finalRadius = pCb.getMaterialRevealViewStartFinalRadius(); 689b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = 69098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView); 6911558893b873cd55b2df779f594f1de3c370d3328Adam Cohen Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2, 6921558893b873cd55b2df779f594f1de3c370d3328Adam Cohen height / 2, revealRadius, finalRadius); 693b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 694b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 695b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setStartDelay(itemsAlphaStagger); 696b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 697b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 698b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 699006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(reveal); 700b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 701b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 702b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 703a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham dispatchOnLauncherTransitionPrepare(fromView, animated, true); 704a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham dispatchOnLauncherTransitionPrepare(toView, animated, true); 705a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham 706006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 707b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 708b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 709b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.setVisibility(View.GONE); 710b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, true); 711b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, true); 712b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 713b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Run any queued runnables 714b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (onCompleteRunnable != null) { 715b745afbdd75157c73d581b345118cdaff99e912dWinson Chung onCompleteRunnable.run(); 716b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 717b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 718b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Disable all necessary layers 719b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 720b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 721b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_NONE, null); 722b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 723b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 724b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 725b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Reset page transforms 726b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (contentView != null) { 727b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationX(0); 728b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 729b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1); 730b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 731b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 732b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 733006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 73476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 738006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet stateAnimation = animation; 739b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Runnable startAnimRunnable = new Runnable() { 740756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal @TargetApi(Build.VERSION_CODES.LOLLIPOP) 741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void run() { 742006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Check that mCurrentAnimation hasn't changed while 743b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // we waited for a layout/draw pass 744006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != stateAnimation) 745b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return; 746006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 747b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 748b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 750b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Enable all necessary layers 751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 754b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 755756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 756b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.buildLayer(); 757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 758b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 759006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung stateAnimation.start(); 760b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 761b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 762b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.post(startAnimRunnable); 763006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 764006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung return animation; 7656d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else /* if (!(animated && initialized)) */ { 766b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.setVisibility(View.GONE); 767b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, true); 768b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, true); 769b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, true); 770b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, true); 771b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, true); 772b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, true); 77376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 774b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 775b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Run any queued runnables 776b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (onCompleteRunnable != null) { 777b745afbdd75157c73d581b345118cdaff99e912dWinson Chung onCompleteRunnable.run(); 778b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 779006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 780006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung return null; 781b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 782b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 783b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 784006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung /** 785b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the prepare-transition event to suitable views. 786b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 787b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) { 788b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 789b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated, 790b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 791b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 792b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 793b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 794b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 795b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the start-transition event to suitable views. 796b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 797b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) { 798b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 799b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated, 800b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 801b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 802b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 803b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Update the workspace transition step as well 804b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStep(v, 0f); 805b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 806b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 807b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 808b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the step-transition event to suitable views. 809b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 810b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionStep(View v, float t) { 811b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 812b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t); 813b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 814b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 815b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 816b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 817b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the end-transition event to suitable views. 818b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 819b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) { 820b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 821b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated, 822b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 823b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 824b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 825b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Update the workspace transition step as well 826b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStep(v, 1f); 827b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 828b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 829b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 830b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Cancels the current animation. 831b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 832b745afbdd75157c73d581b345118cdaff99e912dWinson Chung private void cancelAnimation() { 833006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != null) { 834006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.setDuration(0); 835006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.cancel(); 836006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 837b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 838b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 839006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 840d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal @Thunk void cleanupAnimation() { 841006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 842006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung } 8431558893b873cd55b2df779f594f1de3c370d3328Adam Cohen} 844