LauncherStateTransitionAnimation.java revision db364379312e56a3a3905a54d0de783062a92a73
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; 26756cd26592dee6b956becdc24d60995c64de9153Sunny Goyalimport android.annotation.TargetApi; 27b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.content.res.Resources; 28756cd26592dee6b956becdc24d60995c64de9153Sunny Goyalimport android.os.Build; 29b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.util.Log; 30b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.View; 31b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.AccelerateInterpolator; 32db364379312e56a3a3905a54d0de783062a92a73Sunny Goyalimport android.view.animation.Animation; 33b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.DecelerateInterpolator; 341558893b873cd55b2df779f594f1de3c370d3328Adam Cohen 355f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chungimport com.android.launcher3.allapps.AllAppsContainerView; 36645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Songimport com.android.launcher3.allapps.AllAppsTransitionController; 37b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyalimport com.android.launcher3.anim.AnimationLayerSet; 38645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Songimport com.android.launcher3.config.FeatureFlags; 398f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickhamimport com.android.launcher3.util.CircleRevealOutlineProvider; 40091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 413f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport com.android.launcher3.widget.WidgetsContainerView; 421558893b873cd55b2df779f594f1de3c370d3328Adam Cohen 43b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/** 44b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * TODO: figure out what kind of tests we can write for this 45b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * 46b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Things to test when changing the following class. 47b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Home from workspace 48b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from center screen 49b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from other screens 50b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Home from all apps 51b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from center screen 52b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from other screens 53b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Back from all apps 54b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from center screen 55b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from other screens 56b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Launch app from workspace and quit 57b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 58b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 59b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Launch app from all apps and quit 60b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 61b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 62b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Go to a screen that's not the default, then all 63b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * apps, and launch and app, and go back 64b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 65b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * -with home 66b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On workspace, long press power and go back 67b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 68b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 69b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On all apps, long press power and go back 70b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 71b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 72b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On workspace, power off 73b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On all apps, power off 74b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Launch an app and turn off the screen while in that app 75b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Go back with home key 76b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Go back with back key TODO: make this not go to workspace 77b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From all apps 78b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From workspace 79b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Enter and exit car mode (becuase it causes an extra configuration changed) 80b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From all apps 81b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From the center workspace 82b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From another workspace 83b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 84b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpublic class LauncherStateTransitionAnimation { 85b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 86645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song /** 87645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song * animation used for all apps and widget tray when 88645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song *{@link FeatureFlags#LAUNCHER3_ALL_APPS_PULL_UP} is {@code false} 89645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song */ 90645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public static final int CIRCULAR_REVEAL = 0; 91645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song /** 92645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song * animation used for all apps and not widget tray when 93645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song *{@link FeatureFlags#LAUNCHER3_ALL_APPS_PULL_UP} is {@code true} 94645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song */ 95645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public static final int PULLUP = 1; 96645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 970ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private static final float FINAL_REVEAL_ALPHA_FOR_WIDGETS = 0.3f; 980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 99b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 100b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Private callbacks made during transition setup. 101b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 1020ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private static class PrivateTransitionCallbacks { 1030ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private final float materialRevealViewFinalAlpha; 1040ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 1050ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks(float revealAlpha) { 1060ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal materialRevealViewFinalAlpha = revealAlpha; 107b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 1080ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 109b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewStartFinalRadius() { 110b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return 0; 111b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 112b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(View revealView, 11398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song View buttonView) { 114b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return null; 115b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 11676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung void onTransitionComplete() {} 117b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 118b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1190ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal public static final String TAG = "LSTAnimation"; 120b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 121b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public static final int SINGLE_FRAME_DELAY = 16; 122b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 123091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk Launcher mLauncher; 124006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung @Thunk AnimatorSet mCurrentAnimation; 125645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song AllAppsTransitionController mAllAppsController; 126b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 127645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public LauncherStateTransitionAnimation(Launcher l, AllAppsTransitionController allAppsController) { 128b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mLauncher = l; 129645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song mAllAppsController = allAppsController; 130b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 131b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 132b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 133b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts an animation to the apps view. 13476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * 13576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * @param startSearchAfterTransition Immediately starts app search after the transition to 13676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * All Apps is completed. 137b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 138db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal public void startAnimationToAllApps( 139006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final boolean animated, final boolean startSearchAfterTransition) { 1405f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final AllAppsContainerView toView = mLauncher.getAppsView(); 141bb011dad4e69bec027be1e00d573a3095b318b43Sunny Goyal final View buttonView = mLauncher.getStartViewForAllAppsRevealAnimation(); 1420ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) { 143b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 144b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public float getMaterialRevealViewStartFinalRadius() { 1452e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; 146b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return allAppsButtonSize / 2; 147b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 148b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 149b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 150b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View revealView, final View allAppsButtonView) { 151b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 152b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationStart(Animator animation) { 153b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.INVISIBLE); 154b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 155b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 156b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.VISIBLE); 157b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 158b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 159b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 16076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung @Override 16176648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung void onTransitionComplete() { 162aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 16376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung if (startSearchAfterTransition) { 16476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung toView.startAppsSearch(); 16576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung } 16676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung } 167b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 168645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song int animType = CIRCULAR_REVEAL; 169645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) { 170645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animType = PULLUP; 171645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 172ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating from spring loaded mode back to all apps 173db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal startAnimationToOverlay( 174645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song Workspace.State.NORMAL_HIDDEN, buttonView, toView, animated, animType, cb); 175b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 176b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 177b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 178b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts an animation to the widgets view. 179b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 180db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal public void startAnimationToWidgets(final boolean animated) { 1813f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song final WidgetsContainerView toView = mLauncher.getWidgetsView(); 18298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View buttonView = mLauncher.getWidgetsButton(); 183db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal startAnimationToOverlay( 184645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song Workspace.State.OVERVIEW_HIDDEN, buttonView, toView, animated, CIRCULAR_REVEAL, 1858fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS){ 1868fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 1878fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 188aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 1898fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 1908fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song }); 191b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 192b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 193b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 1946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the current overlay view. 195b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 196b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void startAnimationToWorkspace(final Launcher.State fromState, 197006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 1982a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final boolean animated, final Runnable onCompleteRunnable) { 199b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (toWorkspaceState != Workspace.State.NORMAL && 200b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspaceState != Workspace.State.SPRING_LOADED && 201b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspaceState != Workspace.State.OVERVIEW) { 202b745afbdd75157c73d581b345118cdaff99e912dWinson Chung Log.e(TAG, "Unexpected call to startAnimationToWorkspace"); 203b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 204b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 2059dcf0a3ef7595f58aedec7773e7bc3b9075fb3caHyunyoung Song if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED 2069dcf0a3ef7595f58aedec7773e7bc3b9075fb3caHyunyoung Song || mAllAppsController.isTransitioning()) { 207645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song int animType = CIRCULAR_REVEAL; 208645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) { 209645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animType = PULLUP; 210645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 2112a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson startAnimationToWorkspaceFromAllApps(fromWorkspaceState, toWorkspaceState, 212645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, animType, onCompleteRunnable); 2136d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else if (fromState == Launcher.State.WIDGETS || 2146d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham fromState == Launcher.State.WIDGETS_SPRING_LOADED) { 2152a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson startAnimationToWorkspaceFromWidgets(fromWorkspaceState, toWorkspaceState, 216dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung animated, onCompleteRunnable); 2176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else { 2186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham startAnimationToNewWorkspaceState(fromWorkspaceState, toWorkspaceState, 2196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham animated, onCompleteRunnable); 220b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 221b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 222b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 223b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 224b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to a particular overlay view. 225b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 226191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song private void startAnimationToOverlay( 227db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal final Workspace.State toWorkspaceState, 2280ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View buttonView, final BaseContainerView toView, 229645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final boolean animated, int animType, final PrivateTransitionCallbacks pCb) { 230006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 231b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 2329fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal final boolean material = Utilities.ATLEAST_LOLLIPOP; 2335f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 234e3876e8dd0a6b6948c5365af9f88709301bbb536Hyunyoung Song final int revealDurationSlide = res.getInteger(R.integer.config_overlaySlideRevealTime); 235e3876e8dd0a6b6948c5365af9f88709301bbb536Hyunyoung Song 2360ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final int itemsAlphaStagger = res.getInteger(R.integer.config_overlayItemsAlphaStagger); 237b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 238b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal final AnimationLayerSet layerViews = new AnimationLayerSet(); 239b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 240b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 24198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 242b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 243b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 244b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 245b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 2460ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View contentView = toView.getContentView(); 247db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal playCommonTransitionAnimations(toWorkspaceState, 24861d9e78f23efcf43be1945d4233780ac89db99d9Winson animated, initialized, animation, layerViews); 249645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (!animated || !initialized) { 250ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && 251ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song toWorkspaceState == Workspace.State.NORMAL_HIDDEN) { 252ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song mAllAppsController.finishPullUp(); 253ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song } 254645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setTranslationX(0.0f); 255645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setTranslationY(0.0f); 256645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setScaleX(1.0f); 257645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setScaleY(1.0f); 258645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setAlpha(1.0f); 259645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setVisibility(View.VISIBLE); 260645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 261645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Show the content view 262645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song contentView.setVisibility(View.VISIBLE); 263645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 264191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song return; 265645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 266645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (animType == CIRCULAR_REVEAL) { 267b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the reveal view animation 2680ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View revealView = toView.getRevealView(); 2690ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 270b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 271b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 272f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 273b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 274b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(0f); 275b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0f); 276b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationX(0f); 277b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 278b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 279b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha; 280b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 281b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 282b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 2830ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace( 2840ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal revealView, buttonView, null); 2850ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal revealViewToAlpha = pCb.materialRevealViewFinalAlpha; 28698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 28798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 289b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToAlpha = 0f; 290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 294b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the animators 295b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelAlpha = 2965d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f); 297b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftY = 2985d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0); 299b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftX = 3005d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0); 301b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView, 302b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha, panelDriftY, panelDriftX); 303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setDuration(revealDuration); 304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 305b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Play the animation 307b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal layerViews.addView(revealView); 308006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlphaAndDrift); 309b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 311b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setVisibility(View.VISIBLE); 312b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(0f); 313b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(revealViewToYDrift); 314b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal layerViews.addView(contentView); 315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 316b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift, 0); 319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration); 320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger); 322006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 323b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f); 325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(revealDuration); 326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setStartDelay(itemsAlphaStagger); 328006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float startRadius = pCb.getMaterialRevealViewStartFinalRadius(); 332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener( 33398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealView, buttonView); 3348f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2, 3358f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham startRadius, revealRadius).createRevealAnimator(revealView); 336b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 337b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 338b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 341006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(reveal); 342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 343b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 344006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 347b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 348b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 349b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 350b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 351006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 35276648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 354b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 355b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 357b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.bringToFront(); 358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setVisibility(View.VISIBLE); 359b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal 360b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal animation.addListener(layerViews); 361db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal toView.post(new StartAnimRunnable(animation, toView)); 362191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song mCurrentAnimation = animation; 363645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } else if (animType == PULLUP) { 36461d9e78f23efcf43be1945d4233780ac89db99d9Winson // We are animating the content view alpha, so ensure we have a layer for it 365b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal layerViews.addView(contentView); 36661d9e78f23efcf43be1945d4233780ac89db99d9Winson 367645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animation.addListener(new AnimatorListenerAdapter() { 368191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song @Override 369191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song public void onAnimationEnd(Animator animation) { 370191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song cleanupAnimation(); 371191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song pCb.onTransitionComplete(); 372191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } 373645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }); 374191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song boolean shouldPost = mAllAppsController.animateToAllApps(animation, revealDurationSlide); 375b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 376db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal Runnable startAnimRunnable = new StartAnimRunnable(animation, toView); 377191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song mCurrentAnimation = animation; 378b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal mCurrentAnimation.addListener(layerViews); 379191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song if (shouldPost) { 380191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song toView.post(startAnimRunnable); 381191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } else { 382191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimRunnable.run(); 383191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } 384b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 386b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 387b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 388685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham * Plays animations used by various transitions. 389685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham */ 3907c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal private void playCommonTransitionAnimations( 391db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal Workspace.State toWorkspaceState, 39261d9e78f23efcf43be1945d4233780ac89db99d9Winson boolean animated, boolean initialized, AnimatorSet animation, 393b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal AnimationLayerSet layerViews) { 394685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Create the workspace animation. 395685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // NOTE: this call apparently also sets the state for the workspace if !animated 396685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState, 397685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animated, layerViews); 398685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 399685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham if (animated && initialized) { 400685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Play the workspace animation 401685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham if (workspaceAnim != null) { 402685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animation.play(workspaceAnim); 403685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 404685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 405685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 406685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 407685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham /** 4086d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the apps view. 409b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 410006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState, 411645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final Workspace.State toWorkspaceState, final boolean animated, int type, 4122a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 413db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal final AllAppsContainerView appsView = mLauncher.getAppsView(); 4140ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal // No alpha anim from all apps 4150ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) { 416b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 417b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewStartFinalRadius() { 4182e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; 419b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return allAppsButtonSize / 2; 420b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 421b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 422b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 423b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View revealView, final View allAppsButtonView) { 424b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 425b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationStart(Animator animation) { 426b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // We set the alpha instead of visibility to ensure that the focus does not 427b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // get taken from the all apps view 428b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.VISIBLE); 429b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(0f); 430b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 431b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 432b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 433b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 434b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 435b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Show the all apps button, and focus it 436b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(1f); 437b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 438b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 439b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 4408fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 4418fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 442aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 443db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal appsView.reset(); 4448fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 445b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 446ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating to spring loaded mode from all apps 447191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState, 448bb011dad4e69bec027be1e00d573a3095b318b43Sunny Goyal mLauncher.getStartViewForAllAppsRevealAnimation(), appsView, 449645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, type, onCompleteRunnable, cb); 450b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 451b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 452b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 4536d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the widgets view. 454b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 455006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState, 4566d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Workspace.State toWorkspaceState, final boolean animated, 4572a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 4584cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song final WidgetsContainerView widgetsView = mLauncher.getWidgetsView(); 4590ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = 4600ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS) { 461b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 462b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 46398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View revealView, final View widgetsButtonView) { 464b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 465b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 466b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 467b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 468b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 469b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 470b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 4718fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 4728fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 473aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 4748fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 475b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 476191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimationToWorkspaceFromOverlay( 4770ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal fromWorkspaceState, toWorkspaceState, 4787c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal mLauncher.getWidgetsButton(), widgetsView, 479645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, CIRCULAR_REVEAL, onCompleteRunnable, cb); 480b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 481b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 482b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 4836d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from another workspace state, e.g. normal to overview. 4846d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham */ 4856d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham private void startAnimationToNewWorkspaceState(final Workspace.State fromWorkspaceState, 4866d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Workspace.State toWorkspaceState, final boolean animated, 4876d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Runnable onCompleteRunnable) { 4886d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final View fromWorkspace = mLauncher.getWorkspace(); 489b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal final AnimationLayerSet layerViews = new AnimationLayerSet(); 4906d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 4916d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 4926d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Cancel the current animation 4936d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham cancelAnimation(); 4946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 495db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal playCommonTransitionAnimations(toWorkspaceState, animated, animated, animation, layerViews); 496f3e35d93318190f995e6a0fc9d0441ac844b67e4Jon Miranda mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 497f3e35d93318190f995e6a0fc9d0441ac844b67e4Jon Miranda 4986d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (animated) { 4996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham animation.addListener(new AnimatorListenerAdapter() { 5006d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham @Override 5016d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham public void onAnimationEnd(Animator animation) { 5026d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Run any queued runnables 5036d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (onCompleteRunnable != null) { 5046d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham onCompleteRunnable.run(); 5056d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5066d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5076d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // This can hold unnecessary references to views. 5086d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham cleanupAnimation(); 5096d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5106d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham }); 511db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal animation.addListener(layerViews); 512db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal fromWorkspace.post(new StartAnimRunnable(animation, null)); 5136d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham mCurrentAnimation = animation; 5146d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else /* if (!animated) */ { 5156d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Run any queued runnables 5166d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (onCompleteRunnable != null) { 5176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham onCompleteRunnable.run(); 5186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5206d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham mCurrentAnimation = null; 5216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5246d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham /** 525b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to the workspace. 526b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 527191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song private void startAnimationToWorkspaceFromOverlay( 5280ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 5290ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View buttonView, final BaseContainerView fromView, 530645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final boolean animated, int animType, final Runnable onCompleteRunnable, 531006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final PrivateTransitionCallbacks pCb) { 532006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 533b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 5349fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal final boolean material = Utilities.ATLEAST_LOLLIPOP; 5355f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 536e3876e8dd0a6b6948c5365af9f88709301bbb536Hyunyoung Song final int revealDurationSlide = res.getInteger(R.integer.config_overlaySlideRevealTime); 537b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final int itemsAlphaStagger = 5385f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung res.getInteger(R.integer.config_overlayItemsAlphaStagger); 539b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 540b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View toView = mLauncher.getWorkspace(); 54161d9e78f23efcf43be1945d4233780ac89db99d9Winson final View revealView = fromView.getRevealView(); 54261d9e78f23efcf43be1945d4233780ac89db99d9Winson final View contentView = fromView.getContentView(); 543b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 544b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal final AnimationLayerSet layerViews = new AnimationLayerSet(); 545b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 546b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 54798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 548b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 549b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 550b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 551b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 552db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal playCommonTransitionAnimations(toWorkspaceState, 55361d9e78f23efcf43be1945d4233780ac89db99d9Winson animated, initialized, animation, layerViews); 55474b5af35291f620d2f09f313f2e9bd9f817b9d27Hyunyoung Song if (!animated || !initialized) { 555ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && 556ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song fromWorkspaceState == Workspace.State.NORMAL_HIDDEN) { 5577ccc4625e38b8107cd1882272aec36967874a5ccHyunyoung Song mAllAppsController.finishPullDown(); 558b11ae50fcb2bb07ee77645fdacdf90f67f58dae4Hyunyoung Song } 559645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song fromView.setVisibility(View.GONE); 560645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 5610bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 562645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Run any queued runnables 563645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (onCompleteRunnable != null) { 564645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song onCompleteRunnable.run(); 565645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 566191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song return; 567645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 568645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (animType == CIRCULAR_REVEAL) { 569b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // hideAppsCustomizeHelper is called in some cases when it is already hidden 570b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // don't perform all these no-op animations. In particularly, this was causing 571b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // the all-apps button to pop in and out. 572b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (fromView.getVisibility() == View.VISIBLE) { 573b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 574b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 575f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 576b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 577b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(1f); 578b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0); 579b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal layerViews.addView(revealView); 580b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 581b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 582b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 583b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 584b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 58598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, 58698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song buttonView, null); 58798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 58898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 589b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 590b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 591b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 592b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 593b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 594b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // The vertical motion of the apps panel should be delayed by one frame 595b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // from the conceal animation in order to give the right feel. We correspondingly 596b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // shorten the duration so that the slide and conceal end at the same time. 597b745afbdd75157c73d581b345118cdaff99e912dWinson Chung TimeInterpolator decelerateInterpolator = material ? 598b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new LogDecelerateInterpolator(100, 0) : 599b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new DecelerateInterpolator(1f); 6001558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY", 601b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 602b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY); 603b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 604b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setInterpolator(decelerateInterpolator); 605006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftY); 606b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 6071558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX", 608b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToXDrift); 609b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY); 610b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 611b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setInterpolator(decelerateInterpolator); 612006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftX); 613b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 614b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup animation for the reveal panel alpha 615b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha = !material ? 0f : 6160ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal pCb.materialRevealViewFinalAlpha; 617b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (revealViewToAlpha != 1f) { 6181558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha", 619b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1f, revealViewToAlpha); 620b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setDuration(material ? revealDuration : 150); 621b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY); 622b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setInterpolator(decelerateInterpolator); 623006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlpha); 624b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 625b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 626b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 627b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal layerViews.addView(contentView); 628b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 629b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 6301558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 631b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 632b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 633b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY); 634b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(decelerateInterpolator); 635b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 636006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 637b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 638b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1f); 6391558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f); 640b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(100); 641b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(decelerateInterpolator); 642006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 643b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 6443f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham // Invalidate the scrim throughout the animation to ensure the highlight 6453f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham // cutout is correct throughout. 6463f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham ValueAnimator invalidateScrim = ValueAnimator.ofFloat(0f, 1f); 6473f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham invalidateScrim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 6483f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham @Override 6493f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham public void onAnimationUpdate(ValueAnimator animation) { 6503f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham mLauncher.getDragLayer().invalidateScrim(); 6513f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham } 6523f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham }); 6533f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham animation.play(invalidateScrim); 6543f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham 655b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 656b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Animate the all apps button 657b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float finalRadius = pCb.getMaterialRevealViewStartFinalRadius(); 658b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = 65998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView); 6608f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2, 6618f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham revealRadius, finalRadius).createRevealAnimator(revealView); 662b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 663b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 664b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setStartDelay(itemsAlphaStagger); 665b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 666b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 667b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 668006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(reveal); 669b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 670b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 671b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 672006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 673b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 674b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 675b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.setVisibility(View.GONE); 676b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Run any queued runnables 677b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (onCompleteRunnable != null) { 678b745afbdd75157c73d581b345118cdaff99e912dWinson Chung onCompleteRunnable.run(); 679b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 680b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 681b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Reset page transforms 682b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (contentView != null) { 683b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationX(0); 684b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 685b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1); 686b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 687b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 688b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 689006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 69076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 691b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 692b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 693b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 694191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song mCurrentAnimation = animation; 695b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal mCurrentAnimation.addListener(layerViews); 696db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal fromView.post(new StartAnimRunnable(animation, null)); 697645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } else if (animType == PULLUP) { 69861d9e78f23efcf43be1945d4233780ac89db99d9Winson // We are animating the content view alpha, so ensure we have a layer for it 699b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal layerViews.addView(contentView); 70061d9e78f23efcf43be1945d4233780ac89db99d9Winson 701645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animation.addListener(new AnimatorListenerAdapter() { 702eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song boolean canceled = false; 703645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song @Override 704eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song public void onAnimationCancel(Animator animation) { 705eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song canceled = true; 706645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 707b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 708645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song @Override 709645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void onAnimationEnd(Animator animation) { 710eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song if (canceled) return; 711645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Run any queued runnables 712645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (onCompleteRunnable != null) { 713645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song onCompleteRunnable.run(); 714645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 71561d9e78f23efcf43be1945d4233780ac89db99d9Winson 716645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song cleanupAnimation(); 717645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 718645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 719eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song 720645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }); 721191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song boolean shouldPost = mAllAppsController.animateToWorkspace(animation, revealDurationSlide); 722eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song 723db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal Runnable startAnimRunnable = new StartAnimRunnable(animation, toView); 724191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song mCurrentAnimation = animation; 725b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal mCurrentAnimation.addListener(layerViews); 726191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song if (shouldPost) { 727191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song fromView.post(startAnimRunnable); 728191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } else { 729191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimRunnable.run(); 730191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } 731b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 732191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song return; 733b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 734b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 735006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung /** 736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Cancels the current animation. 737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 738b745afbdd75157c73d581b345118cdaff99e912dWinson Chung private void cancelAnimation() { 739006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != null) { 740006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.setDuration(0); 741006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.cancel(); 742006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 743b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 744b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 745006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 746d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal @Thunk void cleanupAnimation() { 747006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 748006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung } 749db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal 750db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal private class StartAnimRunnable implements Runnable { 751db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal 752db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal private final AnimatorSet mAnim; 753db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal private final View mViewToFocus; 754db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal 755db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal public StartAnimRunnable(AnimatorSet anim, View viewToFocus) { 756db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal mAnim = anim; 757db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal mViewToFocus = viewToFocus; 758db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal } 759db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal 760db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal @Override 761db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal public void run() { 762db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal if (mCurrentAnimation != mAnim) { 763db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal return; 764db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal } 765db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal if (mViewToFocus != null) { 766db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal mViewToFocus.requestFocus(); 767db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal } 768db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal mAnim.start(); 769db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal } 770db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal } 7711558893b873cd55b2df779f594f1de3c370d3328Adam Cohen} 772