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; 26b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.content.res.Resources; 27b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.util.Log; 28b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.View; 29b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.AccelerateInterpolator; 301558893b873cd55b2df779f594f1de3c370d3328Adam Cohen 315f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chungimport com.android.launcher3.allapps.AllAppsContainerView; 32645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Songimport com.android.launcher3.allapps.AllAppsTransitionController; 33b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyalimport com.android.launcher3.anim.AnimationLayerSet; 34645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Songimport com.android.launcher3.config.FeatureFlags; 358f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickhamimport com.android.launcher3.util.CircleRevealOutlineProvider; 36091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 373f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport com.android.launcher3.widget.WidgetsContainerView; 381558893b873cd55b2df779f594f1de3c370d3328Adam Cohen 39b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/** 40b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * TODO: figure out what kind of tests we can write for this 41b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * 42b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Things to test when changing the following class. 43b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Home from workspace 44b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from center screen 45b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from other screens 46b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Home from all apps 47b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from center screen 48b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from other screens 49b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Back from all apps 50b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from center screen 51b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from other screens 52b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Launch app from workspace and quit 53b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 54b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 55b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Launch app from all apps and quit 56b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 57b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 58b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Go to a screen that's not the default, then all 59b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * apps, and launch and app, and go back 60b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 61b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * -with home 62b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On workspace, long press power and go back 63b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 64b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 65b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On all apps, long press power and go back 66b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 67b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 68b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On workspace, power off 69b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On all apps, power off 70b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Launch an app and turn off the screen while in that app 71b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Go back with home key 72b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Go back with back key TODO: make this not go to workspace 73b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From all apps 74b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From workspace 75b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Enter and exit car mode (becuase it causes an extra configuration changed) 76b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From all apps 77b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From the center workspace 78b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From another workspace 79b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 80b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpublic class LauncherStateTransitionAnimation { 81b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 82645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song /** 83645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song * animation used for all apps and widget tray when 84645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song *{@link FeatureFlags#LAUNCHER3_ALL_APPS_PULL_UP} is {@code false} 85645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song */ 86645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public static final int CIRCULAR_REVEAL = 0; 87645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song /** 88645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song * animation used for all apps and not widget tray when 89645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song *{@link FeatureFlags#LAUNCHER3_ALL_APPS_PULL_UP} is {@code true} 90645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song */ 91645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public static final int PULLUP = 1; 92645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 930ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private static final float FINAL_REVEAL_ALPHA_FOR_WIDGETS = 0.3f; 940ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 95b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 96b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Private callbacks made during transition setup. 97b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private static class PrivateTransitionCallbacks { 990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private final float materialRevealViewFinalAlpha; 1000ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 1010ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks(float revealAlpha) { 1020ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal materialRevealViewFinalAlpha = revealAlpha; 103b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 1040ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 105b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewStartFinalRadius() { 106b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return 0; 107b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 108b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(View revealView, 10998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song View buttonView) { 110b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return null; 111b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 11276648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung void onTransitionComplete() {} 113b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 114b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1150ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal public static final String TAG = "LSTAnimation"; 116b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 117b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public static final int SINGLE_FRAME_DELAY = 16; 118b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 119091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk Launcher mLauncher; 120006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung @Thunk AnimatorSet mCurrentAnimation; 121645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song AllAppsTransitionController mAllAppsController; 122b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 123645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public LauncherStateTransitionAnimation(Launcher l, AllAppsTransitionController allAppsController) { 124b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mLauncher = l; 125645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song mAllAppsController = allAppsController; 126b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 127b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 128b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 129b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts an animation to the apps view. 13076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * 13176648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * @param startSearchAfterTransition Immediately starts app search after the transition to 13276648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * All Apps is completed. 133b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 134db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal public void startAnimationToAllApps( 135006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final boolean animated, final boolean startSearchAfterTransition) { 1365f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final AllAppsContainerView toView = mLauncher.getAppsView(); 137bb011dad4e69bec027be1e00d573a3095b318b43Sunny Goyal final View buttonView = mLauncher.getStartViewForAllAppsRevealAnimation(); 1380ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) { 139b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 140b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public float getMaterialRevealViewStartFinalRadius() { 1412e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; 142b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return allAppsButtonSize / 2; 143b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 144b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 145b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 146b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View revealView, final View allAppsButtonView) { 147b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 148b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationStart(Animator animation) { 149b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.INVISIBLE); 150b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 151b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 152b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.VISIBLE); 153b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 154b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 155b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 15676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung @Override 15776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung void onTransitionComplete() { 158aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 15976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung if (startSearchAfterTransition) { 16076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung toView.startAppsSearch(); 16176648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung } 16276648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung } 163b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 164645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song int animType = CIRCULAR_REVEAL; 165645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) { 166645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animType = PULLUP; 167645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 168ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating from spring loaded mode back to all apps 169db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal startAnimationToOverlay( 170645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song Workspace.State.NORMAL_HIDDEN, buttonView, toView, animated, animType, cb); 171b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 172b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 173b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 174b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts an animation to the widgets view. 175b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 176db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal public void startAnimationToWidgets(final boolean animated) { 1773f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song final WidgetsContainerView toView = mLauncher.getWidgetsView(); 17898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View buttonView = mLauncher.getWidgetsButton(); 179db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal startAnimationToOverlay( 180645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song Workspace.State.OVERVIEW_HIDDEN, buttonView, toView, animated, CIRCULAR_REVEAL, 1818fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS){ 1828fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 1838fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 184aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 1858fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 1868fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song }); 187b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 188b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 189b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 1906d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the current overlay view. 191b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 192b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void startAnimationToWorkspace(final Launcher.State fromState, 193006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 1942a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final boolean animated, final Runnable onCompleteRunnable) { 195b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (toWorkspaceState != Workspace.State.NORMAL && 196b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspaceState != Workspace.State.SPRING_LOADED && 197b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspaceState != Workspace.State.OVERVIEW) { 198b745afbdd75157c73d581b345118cdaff99e912dWinson Chung Log.e(TAG, "Unexpected call to startAnimationToWorkspace"); 199b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 200b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 2019dcf0a3ef7595f58aedec7773e7bc3b9075fb3caHyunyoung Song if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED 2029dcf0a3ef7595f58aedec7773e7bc3b9075fb3caHyunyoung Song || mAllAppsController.isTransitioning()) { 203645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song int animType = CIRCULAR_REVEAL; 204645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) { 205645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animType = PULLUP; 206645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 2072a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson startAnimationToWorkspaceFromAllApps(fromWorkspaceState, toWorkspaceState, 208645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, animType, onCompleteRunnable); 2096d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else if (fromState == Launcher.State.WIDGETS || 2106d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham fromState == Launcher.State.WIDGETS_SPRING_LOADED) { 2112a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson startAnimationToWorkspaceFromWidgets(fromWorkspaceState, toWorkspaceState, 212dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung animated, onCompleteRunnable); 2136d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else { 2146d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham startAnimationToNewWorkspaceState(fromWorkspaceState, toWorkspaceState, 2156d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham animated, onCompleteRunnable); 216b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 217b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 218b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 219b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 220b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to a particular overlay view. 221b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 222191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song private void startAnimationToOverlay( 223db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal final Workspace.State toWorkspaceState, 2240ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View buttonView, final BaseContainerView toView, 225645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final boolean animated, int animType, final PrivateTransitionCallbacks pCb) { 226006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 227b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 2285f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 229e3876e8dd0a6b6948c5365af9f88709301bbb536Hyunyoung Song final int revealDurationSlide = res.getInteger(R.integer.config_overlaySlideRevealTime); 230e3876e8dd0a6b6948c5365af9f88709301bbb536Hyunyoung Song 2310ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final int itemsAlphaStagger = res.getInteger(R.integer.config_overlayItemsAlphaStagger); 232b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 233b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal final AnimationLayerSet layerViews = new AnimationLayerSet(); 234b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 235b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 23698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 237b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 238b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 239b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 240b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 2410ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View contentView = toView.getContentView(); 242db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal playCommonTransitionAnimations(toWorkspaceState, 24361d9e78f23efcf43be1945d4233780ac89db99d9Winson animated, initialized, animation, layerViews); 244645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (!animated || !initialized) { 245ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && 246ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song toWorkspaceState == Workspace.State.NORMAL_HIDDEN) { 247ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song mAllAppsController.finishPullUp(); 248ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song } 249645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setTranslationX(0.0f); 250645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setTranslationY(0.0f); 251645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setScaleX(1.0f); 252645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setScaleY(1.0f); 253645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setAlpha(1.0f); 254645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setVisibility(View.VISIBLE); 255645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 256645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Show the content view 257645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song contentView.setVisibility(View.VISIBLE); 258645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 259191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song return; 260645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 261645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (animType == CIRCULAR_REVEAL) { 262b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the reveal view animation 2630ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View revealView = toView.getRevealView(); 2640ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 265b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 266b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 267f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 268b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 269b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(0f); 270b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0f); 271b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationX(0f); 272b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 273b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 274a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal int[] buttonViewToPanelDelta = 275a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal Utilities.getCenterDeltaInScreenSpace(revealView, buttonView); 276a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal final float revealViewToAlpha = pCb.materialRevealViewFinalAlpha; 277a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal final float revealViewToXDrift = buttonViewToPanelDelta[0]; 278a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal final float revealViewToYDrift = buttonViewToPanelDelta[1]; 279b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 280b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the animators 281b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelAlpha = 2825d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f); 283b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftY = 2845d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0); 285b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftX = 2865d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0); 287b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView, 288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha, panelDriftY, panelDriftX); 289b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setDuration(revealDuration); 290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Play the animation 293b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal layerViews.addView(revealView); 294006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlphaAndDrift); 295b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 297b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setVisibility(View.VISIBLE); 298b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(0f); 299b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(revealViewToYDrift); 300b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal layerViews.addView(contentView); 301b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 302b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift, 0); 305b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration); 306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger); 308006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 309b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f); 311b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(revealDuration); 312b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 313b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setStartDelay(itemsAlphaStagger); 314006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 316a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal float startRadius = pCb.getMaterialRevealViewStartFinalRadius(); 317a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener( 318a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal revealView, buttonView); 319a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2, 320a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal startRadius, revealRadius).createRevealAnimator(revealView); 321a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal reveal.setDuration(revealDuration); 322a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 323a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal if (listener != null) { 324a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal reveal.addListener(listener); 325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 326a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal animation.play(reveal); 327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 328006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 335006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 33676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 337b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 338b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 341b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.bringToFront(); 342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setVisibility(View.VISIBLE); 343b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal 344b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal animation.addListener(layerViews); 345db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal toView.post(new StartAnimRunnable(animation, toView)); 346191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song mCurrentAnimation = animation; 347645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } else if (animType == PULLUP) { 34861d9e78f23efcf43be1945d4233780ac89db99d9Winson // We are animating the content view alpha, so ensure we have a layer for it 349b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal layerViews.addView(contentView); 35061d9e78f23efcf43be1945d4233780ac89db99d9Winson 351645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animation.addListener(new AnimatorListenerAdapter() { 352191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song @Override 353191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song public void onAnimationEnd(Animator animation) { 354191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song cleanupAnimation(); 355191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song pCb.onTransitionComplete(); 356191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } 357645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }); 358191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song boolean shouldPost = mAllAppsController.animateToAllApps(animation, revealDurationSlide); 359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 360db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal Runnable startAnimRunnable = new StartAnimRunnable(animation, toView); 361191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song mCurrentAnimation = animation; 362b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal mCurrentAnimation.addListener(layerViews); 363191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song if (shouldPost) { 364191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song toView.post(startAnimRunnable); 365191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } else { 366191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimRunnable.run(); 367191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } 368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 372685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham * Plays animations used by various transitions. 373685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham */ 3747c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal private void playCommonTransitionAnimations( 375db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal Workspace.State toWorkspaceState, 37661d9e78f23efcf43be1945d4233780ac89db99d9Winson boolean animated, boolean initialized, AnimatorSet animation, 377b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal AnimationLayerSet layerViews) { 378685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Create the workspace animation. 379685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // NOTE: this call apparently also sets the state for the workspace if !animated 380685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState, 381685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animated, layerViews); 382685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 383685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham if (animated && initialized) { 384685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Play the workspace animation 385685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham if (workspaceAnim != null) { 386685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animation.play(workspaceAnim); 387685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 388685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 389685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 390685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 391685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham /** 3926d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the apps view. 393b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 394006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState, 395645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final Workspace.State toWorkspaceState, final boolean animated, int type, 3962a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 397db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal final AllAppsContainerView appsView = mLauncher.getAppsView(); 3980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal // No alpha anim from all apps 3990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) { 400b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 401b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewStartFinalRadius() { 4022e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; 403b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return allAppsButtonSize / 2; 404b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 405b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 406b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 407b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View revealView, final View allAppsButtonView) { 408b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 409b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationStart(Animator animation) { 410b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // We set the alpha instead of visibility to ensure that the focus does not 411b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // get taken from the all apps view 412b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.VISIBLE); 413b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(0f); 414b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 415b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 416b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 417b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 418b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 419b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Show the all apps button, and focus it 420b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(1f); 421b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 422b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 423b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 4248fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 4258fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 426aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 427db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal appsView.reset(); 4288fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 429b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 430ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating to spring loaded mode from all apps 431191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState, 432bb011dad4e69bec027be1e00d573a3095b318b43Sunny Goyal mLauncher.getStartViewForAllAppsRevealAnimation(), appsView, 433645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, type, onCompleteRunnable, cb); 434b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 435b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 436b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 4376d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the widgets view. 438b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 439006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState, 4406d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Workspace.State toWorkspaceState, final boolean animated, 4412a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 4424cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song final WidgetsContainerView widgetsView = mLauncher.getWidgetsView(); 4430ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = 4440ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS) { 445b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 446b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 44798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View revealView, final View widgetsButtonView) { 448b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 449b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 450b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 451b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 452b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 453b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 454b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 4558fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 4568fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 457aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 4588fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 459b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 460191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimationToWorkspaceFromOverlay( 4610ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal fromWorkspaceState, toWorkspaceState, 4627c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal mLauncher.getWidgetsButton(), widgetsView, 463645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, CIRCULAR_REVEAL, onCompleteRunnable, cb); 464b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 465b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 466b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 4676d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from another workspace state, e.g. normal to overview. 4686d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham */ 4696d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham private void startAnimationToNewWorkspaceState(final Workspace.State fromWorkspaceState, 4706d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Workspace.State toWorkspaceState, final boolean animated, 4716d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Runnable onCompleteRunnable) { 4726d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final View fromWorkspace = mLauncher.getWorkspace(); 473b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal final AnimationLayerSet layerViews = new AnimationLayerSet(); 4746d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 4756d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 4766d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Cancel the current animation 4776d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham cancelAnimation(); 4786d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 479db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal playCommonTransitionAnimations(toWorkspaceState, animated, animated, animation, layerViews); 480f3e35d93318190f995e6a0fc9d0441ac844b67e4Jon Miranda mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 481f3e35d93318190f995e6a0fc9d0441ac844b67e4Jon Miranda 4826d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (animated) { 4836d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham animation.addListener(new AnimatorListenerAdapter() { 4846d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham @Override 4856d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham public void onAnimationEnd(Animator animation) { 4866d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Run any queued runnables 4876d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (onCompleteRunnable != null) { 4886d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham onCompleteRunnable.run(); 4896d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 4906d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 4916d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // This can hold unnecessary references to views. 4926d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham cleanupAnimation(); 4936d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 4946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham }); 495db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal animation.addListener(layerViews); 496db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal fromWorkspace.post(new StartAnimRunnable(animation, null)); 4976d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham mCurrentAnimation = animation; 4986d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else /* if (!animated) */ { 4996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Run any queued runnables 5006d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (onCompleteRunnable != null) { 5016d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham onCompleteRunnable.run(); 5026d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5036d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5046d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham mCurrentAnimation = null; 5056d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5066d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 5076d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5086d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham /** 509b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to the workspace. 510b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 511191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song private void startAnimationToWorkspaceFromOverlay( 5120ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 5130ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View buttonView, final BaseContainerView fromView, 514645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final boolean animated, int animType, final Runnable onCompleteRunnable, 515006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final PrivateTransitionCallbacks pCb) { 516006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 517b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 5185f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 519e3876e8dd0a6b6948c5365af9f88709301bbb536Hyunyoung Song final int revealDurationSlide = res.getInteger(R.integer.config_overlaySlideRevealTime); 520a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal final int itemsAlphaStagger = res.getInteger(R.integer.config_overlayItemsAlphaStagger); 521b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 522b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View toView = mLauncher.getWorkspace(); 52361d9e78f23efcf43be1945d4233780ac89db99d9Winson final View revealView = fromView.getRevealView(); 52461d9e78f23efcf43be1945d4233780ac89db99d9Winson final View contentView = fromView.getContentView(); 525b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 526b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal final AnimationLayerSet layerViews = new AnimationLayerSet(); 527b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 528b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 52998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 530b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 531b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 532b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 533b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 534db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal playCommonTransitionAnimations(toWorkspaceState, 53561d9e78f23efcf43be1945d4233780ac89db99d9Winson animated, initialized, animation, layerViews); 53674b5af35291f620d2f09f313f2e9bd9f817b9d27Hyunyoung Song if (!animated || !initialized) { 537ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && 538ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song fromWorkspaceState == Workspace.State.NORMAL_HIDDEN) { 5397ccc4625e38b8107cd1882272aec36967874a5ccHyunyoung Song mAllAppsController.finishPullDown(); 540b11ae50fcb2bb07ee77645fdacdf90f67f58dae4Hyunyoung Song } 541645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song fromView.setVisibility(View.GONE); 542645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 5430bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 544645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Run any queued runnables 545645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (onCompleteRunnable != null) { 546645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song onCompleteRunnable.run(); 547645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 548191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song return; 549645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 550645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (animType == CIRCULAR_REVEAL) { 551b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // hideAppsCustomizeHelper is called in some cases when it is already hidden 552b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // don't perform all these no-op animations. In particularly, this was causing 553b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // the all-apps button to pop in and out. 554b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (fromView.getVisibility() == View.VISIBLE) { 555b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 556b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 557f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 558b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 559b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(1f); 560b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0); 561b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal layerViews.addView(revealView); 562b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 563b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 564a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, buttonView); 565a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal final float revealViewToXDrift = buttonViewToPanelDelta[0]; 566a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal final float revealViewToYDrift = buttonViewToPanelDelta[1]; 567b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 568b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // The vertical motion of the apps panel should be delayed by one frame 569b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // from the conceal animation in order to give the right feel. We correspondingly 570b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // shorten the duration so that the slide and conceal end at the same time. 571a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal TimeInterpolator decelerateInterpolator = new LogDecelerateInterpolator(100, 0); 5721558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY", 573b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 574b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY); 575b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 576b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setInterpolator(decelerateInterpolator); 577006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftY); 578b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 5791558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX", 580b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToXDrift); 581b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY); 582b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 583b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setInterpolator(decelerateInterpolator); 584006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftX); 585b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 586b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup animation for the reveal panel alpha 587a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal if (pCb.materialRevealViewFinalAlpha != 1f) { 5881558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha", 589a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal 1f, pCb.materialRevealViewFinalAlpha); 590a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal panelAlpha.setDuration(revealDuration); 591b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setInterpolator(decelerateInterpolator); 592006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlpha); 593b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 594b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 595b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 596b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal layerViews.addView(contentView); 597b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 598b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 5991558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 600b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 601b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 602b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY); 603b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(decelerateInterpolator); 604b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 605006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 606b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 607b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1f); 6081558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f); 609b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(100); 610b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(decelerateInterpolator); 611006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 612b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 6133f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham // Invalidate the scrim throughout the animation to ensure the highlight 6143f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham // cutout is correct throughout. 6153f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham ValueAnimator invalidateScrim = ValueAnimator.ofFloat(0f, 1f); 6163f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham invalidateScrim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 6173f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham @Override 6183f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham public void onAnimationUpdate(ValueAnimator animation) { 6193f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham mLauncher.getDragLayer().invalidateScrim(); 6203f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham } 6213f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham }); 6223f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham animation.play(invalidateScrim); 6233f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham 624a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal // Animate the all apps button 625a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal float finalRadius = pCb.getMaterialRevealViewStartFinalRadius(); 626a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal AnimatorListenerAdapter listener = 627a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView); 628a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2, 629a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal revealRadius, finalRadius).createRevealAnimator(revealView); 630a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 631a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal reveal.setDuration(revealDuration); 632a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal reveal.setStartDelay(itemsAlphaStagger); 633a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal if (listener != null) { 634a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal reveal.addListener(listener); 635b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 636a52ecb0390c85afb385371bb844bb496c59ddf87Sunny Goyal animation.play(reveal); 637b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 638b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 639006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 640b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 641b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 642b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.setVisibility(View.GONE); 643b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Run any queued runnables 644b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (onCompleteRunnable != null) { 645b745afbdd75157c73d581b345118cdaff99e912dWinson Chung onCompleteRunnable.run(); 646b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 647b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 648b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Reset page transforms 649b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (contentView != null) { 650b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationX(0); 651b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 652b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1); 653b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 654b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 655b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 656006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 65776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 658b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 659b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 660b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 661191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song mCurrentAnimation = animation; 662b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal mCurrentAnimation.addListener(layerViews); 663db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal fromView.post(new StartAnimRunnable(animation, null)); 664645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } else if (animType == PULLUP) { 66561d9e78f23efcf43be1945d4233780ac89db99d9Winson // We are animating the content view alpha, so ensure we have a layer for it 666b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal layerViews.addView(contentView); 66761d9e78f23efcf43be1945d4233780ac89db99d9Winson 668645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animation.addListener(new AnimatorListenerAdapter() { 669eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song boolean canceled = false; 670645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song @Override 671eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song public void onAnimationCancel(Animator animation) { 672eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song canceled = true; 673645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 674b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 675645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song @Override 676645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void onAnimationEnd(Animator animation) { 677eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song if (canceled) return; 678645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Run any queued runnables 679645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (onCompleteRunnable != null) { 680645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song onCompleteRunnable.run(); 681645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 68261d9e78f23efcf43be1945d4233780ac89db99d9Winson 683645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song cleanupAnimation(); 684645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 685645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 686eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song 687645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }); 688191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song boolean shouldPost = mAllAppsController.animateToWorkspace(animation, revealDurationSlide); 689eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song 690db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal Runnable startAnimRunnable = new StartAnimRunnable(animation, toView); 691191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song mCurrentAnimation = animation; 692b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal mCurrentAnimation.addListener(layerViews); 693191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song if (shouldPost) { 694191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song fromView.post(startAnimRunnable); 695191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } else { 696191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimRunnable.run(); 697191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } 698b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 699191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song return; 700b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 701b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 702006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung /** 703b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Cancels the current animation. 704b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 705b745afbdd75157c73d581b345118cdaff99e912dWinson Chung private void cancelAnimation() { 706006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != null) { 707006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.setDuration(0); 708006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.cancel(); 709006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 710b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 711b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 712006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 713d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal @Thunk void cleanupAnimation() { 714006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 715006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung } 716db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal 717db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal private class StartAnimRunnable implements Runnable { 718db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal 719db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal private final AnimatorSet mAnim; 720db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal private final View mViewToFocus; 721db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal 722db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal public StartAnimRunnable(AnimatorSet anim, View viewToFocus) { 723db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal mAnim = anim; 724db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal mViewToFocus = viewToFocus; 725db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal } 726db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal 727db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal @Override 728db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal public void run() { 729db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal if (mCurrentAnimation != mAnim) { 730db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal return; 731db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal } 732db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal if (mViewToFocus != null) { 733db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal mViewToFocus.requestFocus(); 734db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal } 735db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal mAnim.start(); 736db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal } 737db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal } 7381558893b873cd55b2df779f594f1de3c370d3328Adam Cohen} 739