LauncherStateTransitionAnimation.java revision 191e9d1b297f3a5dd2953f00c9cf9eac364fcf69
1b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/* 2b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Copyright (C) 2015 The Android Open Source Project 3b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * 4b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 5b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * you may not use this file except in compliance with the License. 6b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * You may obtain a copy of the License at 7b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * 8b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * http://www.apache.org/licenses/LICENSE-2.0 9b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * 10b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Unless required by applicable law or agreed to in writing, software 11b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * distributed under the License is distributed on an "AS IS" BASIS, 12b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * See the License for the specific language governing permissions and 14b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * limitations under the License. 15b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 16b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 17b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpackage com.android.launcher3; 18b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 19b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.Animator; 20b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.AnimatorListenerAdapter; 21b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.AnimatorSet; 22b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.ObjectAnimator; 23b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.PropertyValuesHolder; 24b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.TimeInterpolator; 250bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickhamimport android.animation.ValueAnimator; 267066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyalimport android.annotation.SuppressLint; 27756cd26592dee6b956becdc24d60995c64de9153Sunny Goyalimport android.annotation.TargetApi; 28b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.content.res.Resources; 29756cd26592dee6b956becdc24d60995c64de9153Sunny Goyalimport android.os.Build; 30b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.util.Log; 31b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.View; 32b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.AccelerateInterpolator; 33b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.DecelerateInterpolator; 341558893b873cd55b2df779f594f1de3c370d3328Adam Cohen 355f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chungimport com.android.launcher3.allapps.AllAppsContainerView; 36645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Songimport com.android.launcher3.allapps.AllAppsTransitionController; 37645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Songimport com.android.launcher3.config.FeatureFlags; 388f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickhamimport com.android.launcher3.util.CircleRevealOutlineProvider; 39091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 403f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport com.android.launcher3.widget.WidgetsContainerView; 411558893b873cd55b2df779f594f1de3c370d3328Adam Cohen 42b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport java.util.HashMap; 43b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 44b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/** 45b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * TODO: figure out what kind of tests we can write for this 46b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * 47b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Things to test when changing the following class. 48b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Home from workspace 49b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from center screen 50b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from other screens 51b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Home from all apps 52b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from center screen 53b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from other screens 54b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Back from all apps 55b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from center screen 56b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - from other screens 57b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Launch app from workspace and quit 58b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 59b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 60b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Launch app from all apps and quit 61b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 62b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 63b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Go to a screen that's not the default, then all 64b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * apps, and launch and app, and go back 65b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 66b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * -with home 67b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On workspace, long press power and go back 68b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 69b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 70b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On all apps, long press power and go back 71b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with back 72b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - with home 73b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On workspace, power off 74b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - On all apps, power off 75b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Launch an app and turn off the screen while in that app 76b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Go back with home key 77b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Go back with back key TODO: make this not go to workspace 78b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From all apps 79b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From workspace 80b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - Enter and exit car mode (becuase it causes an extra configuration changed) 81b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From all apps 82b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From the center workspace 83b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * - From another workspace 84b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 85b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpublic class LauncherStateTransitionAnimation { 86b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 87645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song /** 88645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song * animation used for all apps and widget tray when 89645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song *{@link FeatureFlags#LAUNCHER3_ALL_APPS_PULL_UP} is {@code false} 90645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song */ 91645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public static final int CIRCULAR_REVEAL = 0; 92645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song /** 93645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song * animation used for all apps and not widget tray when 94645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song *{@link FeatureFlags#LAUNCHER3_ALL_APPS_PULL_UP} is {@code true} 95645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song */ 96645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public static final int PULLUP = 1; 97645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private static final float FINAL_REVEAL_ALPHA_FOR_WIDGETS = 0.3f; 990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 100b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 101b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Private callbacks made during transition setup. 102b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 1030ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private static class PrivateTransitionCallbacks { 1040ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private final float materialRevealViewFinalAlpha; 1050ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 1060ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks(float revealAlpha) { 1070ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal materialRevealViewFinalAlpha = revealAlpha; 108b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 1090ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 110b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewStartFinalRadius() { 111b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return 0; 112b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 113b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(View revealView, 11498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song View buttonView) { 115b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return null; 116b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 11776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung void onTransitionComplete() {} 118b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 119b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1200ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal public static final String TAG = "LSTAnimation"; 121b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 122b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Flags to determine how to set the layers on views before the transition animation 123b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public static final int BUILD_LAYER = 0; 124b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public static final int BUILD_AND_SET_LAYER = 1; 125b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public static final int SINGLE_FRAME_DELAY = 16; 126b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 127091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk Launcher mLauncher; 128006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung @Thunk AnimatorSet mCurrentAnimation; 129645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song AllAppsTransitionController mAllAppsController; 130b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 131645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public LauncherStateTransitionAnimation(Launcher l, AllAppsTransitionController allAppsController) { 132b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mLauncher = l; 133645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song mAllAppsController = allAppsController; 134b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 135b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 136b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 137b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts an animation to the apps view. 13876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * 13976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * @param startSearchAfterTransition Immediately starts app search after the transition to 14076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung * All Apps is completed. 141b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 142006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung public void startAnimationToAllApps(final Workspace.State fromWorkspaceState, 143006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final boolean animated, final boolean startSearchAfterTransition) { 1445f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final AllAppsContainerView toView = mLauncher.getAppsView(); 145bb011dad4e69bec027be1e00d573a3095b318b43Sunny Goyal final View buttonView = mLauncher.getStartViewForAllAppsRevealAnimation(); 1460ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) { 147b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 148b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public float getMaterialRevealViewStartFinalRadius() { 1492e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; 150b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return allAppsButtonSize / 2; 151b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 152b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 153b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 154b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View revealView, final View allAppsButtonView) { 155b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 156b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationStart(Animator animation) { 157b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.INVISIBLE); 158b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 159b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 160b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.VISIBLE); 161b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 162b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 163b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 16476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung @Override 16576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung void onTransitionComplete() { 166aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 16776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung if (startSearchAfterTransition) { 16876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung toView.startAppsSearch(); 16976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung } 17076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung } 171b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 172645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song int animType = CIRCULAR_REVEAL; 173645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) { 174645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animType = PULLUP; 175645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 176ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating from spring loaded mode back to all apps 177191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimationToOverlay(fromWorkspaceState, 178645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song Workspace.State.NORMAL_HIDDEN, buttonView, toView, animated, animType, cb); 179b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 180b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 181b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 182b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Starts an animation to the widgets view. 183b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 184006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung public void startAnimationToWidgets(final Workspace.State fromWorkspaceState, 185006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final boolean animated) { 1863f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song final WidgetsContainerView toView = mLauncher.getWidgetsView(); 18798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View buttonView = mLauncher.getWidgetsButton(); 188191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimationToOverlay(fromWorkspaceState, 189645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song Workspace.State.OVERVIEW_HIDDEN, buttonView, toView, animated, CIRCULAR_REVEAL, 1908fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS){ 1918fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 1928fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 193aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 1948fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 1958fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song }); 196b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 197b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 198b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 1996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the current overlay view. 200b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 201b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void startAnimationToWorkspace(final Launcher.State fromState, 202006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 2032a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final boolean animated, final Runnable onCompleteRunnable) { 204b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (toWorkspaceState != Workspace.State.NORMAL && 205b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspaceState != Workspace.State.SPRING_LOADED && 206b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspaceState != Workspace.State.OVERVIEW) { 207b745afbdd75157c73d581b345118cdaff99e912dWinson Chung Log.e(TAG, "Unexpected call to startAnimationToWorkspace"); 208b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 209b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 2109dcf0a3ef7595f58aedec7773e7bc3b9075fb3caHyunyoung Song if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED 2119dcf0a3ef7595f58aedec7773e7bc3b9075fb3caHyunyoung Song || mAllAppsController.isTransitioning()) { 212645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song int animType = CIRCULAR_REVEAL; 213645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) { 214645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animType = PULLUP; 215645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 2162a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson startAnimationToWorkspaceFromAllApps(fromWorkspaceState, toWorkspaceState, 217645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, animType, onCompleteRunnable); 2186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else if (fromState == Launcher.State.WIDGETS || 2196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham fromState == Launcher.State.WIDGETS_SPRING_LOADED) { 2202a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson startAnimationToWorkspaceFromWidgets(fromWorkspaceState, toWorkspaceState, 221dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung animated, onCompleteRunnable); 2226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else { 2236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham startAnimationToNewWorkspaceState(fromWorkspaceState, toWorkspaceState, 2246d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham animated, onCompleteRunnable); 225b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 226b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 227b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 228b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 229b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to a particular overlay view. 230b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 2317066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal @SuppressLint("NewApi") 232191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song private void startAnimationToOverlay( 2330ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 2340ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View buttonView, final BaseContainerView toView, 235645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final boolean animated, int animType, final PrivateTransitionCallbacks pCb) { 236006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 237b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 2389fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal final boolean material = Utilities.ATLEAST_LOLLIPOP; 2395f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 240e3876e8dd0a6b6948c5365af9f88709301bbb536Hyunyoung Song final int revealDurationSlide = res.getInteger(R.integer.config_overlaySlideRevealTime); 241e3876e8dd0a6b6948c5365af9f88709301bbb536Hyunyoung Song 2420ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final int itemsAlphaStagger = res.getInteger(R.integer.config_overlayItemsAlphaStagger); 243b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 244b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View fromView = mLauncher.getWorkspace(); 245b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 246b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final HashMap<View, Integer> layerViews = new HashMap<>(); 247b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 248b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 24998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 250b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 251b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 252b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 253b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 2540ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View contentView = toView.getContentView(); 255a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song playCommonTransitionAnimations(toWorkspaceState, fromView, toView, 25661d9e78f23efcf43be1945d4233780ac89db99d9Winson animated, initialized, animation, layerViews); 257645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (!animated || !initialized) { 258ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && 259ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song toWorkspaceState == Workspace.State.NORMAL_HIDDEN) { 260ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song mAllAppsController.finishPullUp(); 261ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song } 262645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setTranslationX(0.0f); 263645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setTranslationY(0.0f); 264645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setScaleX(1.0f); 265645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setScaleY(1.0f); 266645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setAlpha(1.0f); 267645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setVisibility(View.VISIBLE); 268645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.bringToFront(); 269645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 270645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Show the content view 271645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song contentView.setVisibility(View.VISIBLE); 272645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 273645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(fromView, animated, false); 274645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(fromView, animated, false); 275645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, false); 276645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(toView, animated, false); 277645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(toView, animated, false); 278645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, false); 279645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 280191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song return; 281645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 282645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (animType == CIRCULAR_REVEAL) { 283b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the reveal view animation 2840ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View revealView = toView.getRevealView(); 2850ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 286b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 287b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 288f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 289b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(0f); 291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0f); 292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationX(0f); 293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 294b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 295b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha; 296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 297b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 298b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 2990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace( 3000ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal revealView, buttonView, null); 3010ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal revealViewToAlpha = pCb.materialRevealViewFinalAlpha; 30298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 30398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 305b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToAlpha = 0f; 306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 308b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 309b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the animators 311b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelAlpha = 3125d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f); 313b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftY = 3145d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0); 315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftX = 3165d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0); 317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView, 318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha, panelDriftY, panelDriftX); 319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setDuration(revealDuration); 320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 322b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Play the animation 323b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(revealView, BUILD_AND_SET_LAYER); 324006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlphaAndDrift); 325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setVisibility(View.VISIBLE); 328b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(0f); 329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(revealViewToYDrift); 330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(contentView, BUILD_AND_SET_LAYER); 331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift, 0); 335b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration); 336b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 337b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger); 338006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f); 341b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(revealDuration); 342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 343b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setStartDelay(itemsAlphaStagger); 344006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 347b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float startRadius = pCb.getMaterialRevealViewStartFinalRadius(); 348b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener( 34998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealView, buttonView); 3508f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2, 3518f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham startRadius, revealRadius).createRevealAnimator(revealView); 352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 354b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 355b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 357006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(reveal); 358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 360006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 361b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, false); 364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, false); 365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 367b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Disable all necessary layers 370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_NONE, null); 373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 375b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 376b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 377006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 37876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 380b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Dispatch the prepare transition signal 384b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, false); 385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, false); 386b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 387006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet stateAnimation = animation; 388b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Runnable startAnimRunnable = new Runnable() { 389b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void run() { 390006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Check that mCurrentAnimation hasn't changed while 391b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // we waited for a layout/draw pass 392006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != stateAnimation) 393b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return; 394b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 395b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 396b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 397b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Enable all necessary layers 398b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 399b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 400b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 401b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 402756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 403b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.buildLayer(); 404b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 405b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 406b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 407b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Focus the new view 408b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.requestFocus(); 409b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 410006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung stateAnimation.start(); 411b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 412b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 413b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.bringToFront(); 414b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setVisibility(View.VISIBLE); 415b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.post(startAnimRunnable); 416191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song mCurrentAnimation = animation; 417645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } else if (animType == PULLUP) { 41861d9e78f23efcf43be1945d4233780ac89db99d9Winson // We are animating the content view alpha, so ensure we have a layer for it 41961d9e78f23efcf43be1945d4233780ac89db99d9Winson layerViews.put(contentView, BUILD_AND_SET_LAYER); 42061d9e78f23efcf43be1945d4233780ac89db99d9Winson 421645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animation.addListener(new AnimatorListenerAdapter() { 422191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song @Override 423191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song public void onAnimationEnd(Animator animation) { 424191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, false); 425191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, false); 426191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song 427191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song // Disable all necessary layers 428191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song for (View v : layerViews.keySet()) { 429191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 430191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song v.setLayerType(View.LAYER_TYPE_NONE, null); 431191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } 432191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } 433191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song 434191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song cleanupAnimation(); 435191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song pCb.onTransitionComplete(); 436191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } 437645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }); 438191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song boolean shouldPost = mAllAppsController.animateToAllApps(animation, revealDurationSlide); 439b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 440b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, false); 441b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, false); 442006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 443645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final AnimatorSet stateAnimation = animation; 444645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final Runnable startAnimRunnable = new Runnable() { 445645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void run() { 446645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Check that mCurrentAnimation hasn't changed while 447645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // we waited for a layout/draw pass 448645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (mCurrentAnimation != stateAnimation) 449645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return; 45061d9e78f23efcf43be1945d4233780ac89db99d9Winson 451645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(fromView, animated, false); 452645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(toView, animated, false); 453645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 45461d9e78f23efcf43be1945d4233780ac89db99d9Winson // Enable all necessary layers 45561d9e78f23efcf43be1945d4233780ac89db99d9Winson for (View v : layerViews.keySet()) { 45661d9e78f23efcf43be1945d4233780ac89db99d9Winson if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 45761d9e78f23efcf43be1945d4233780ac89db99d9Winson v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 45861d9e78f23efcf43be1945d4233780ac89db99d9Winson } 45961d9e78f23efcf43be1945d4233780ac89db99d9Winson if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 46061d9e78f23efcf43be1945d4233780ac89db99d9Winson v.buildLayer(); 46161d9e78f23efcf43be1945d4233780ac89db99d9Winson } 46261d9e78f23efcf43be1945d4233780ac89db99d9Winson } 46361d9e78f23efcf43be1945d4233780ac89db99d9Winson 464645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.requestFocus(); 465645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song stateAnimation.start(); 466645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 467645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }; 468191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song mCurrentAnimation = animation; 469191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song if (shouldPost) { 470191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song toView.post(startAnimRunnable); 471191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } else { 472191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimRunnable.run(); 473191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } 474b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 475b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 476b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 477b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 478685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham * Plays animations used by various transitions. 479685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham */ 4807c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal private void playCommonTransitionAnimations( 4817c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal Workspace.State toWorkspaceState, View fromView, View toView, 48261d9e78f23efcf43be1945d4233780ac89db99d9Winson boolean animated, boolean initialized, AnimatorSet animation, 483685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham HashMap<View, Integer> layerViews) { 484685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Create the workspace animation. 485685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // NOTE: this call apparently also sets the state for the workspace if !animated 486685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState, 487685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animated, layerViews); 488685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 489685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham if (animated && initialized) { 490685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Play the workspace animation 491685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham if (workspaceAnim != null) { 492685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animation.play(workspaceAnim); 493685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 494685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Dispatch onLauncherTransitionStep() as the animation interpolates. 495685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animation.play(dispatchOnLauncherTransitionStepAnim(fromView, toView)); 496685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 497685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 498685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 499685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham /** 5000bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * Returns an Animator that calls {@link #dispatchOnLauncherTransitionStep(View, float)} on 5010bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * {@param fromView} and {@param toView} as the animation interpolates. 5020bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * 5030bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * This is a bit hacky: we create a dummy ValueAnimator just for the AnimatorUpdateListener. 5040bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham */ 5050bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham private Animator dispatchOnLauncherTransitionStepAnim(final View fromView, final View toView) { 5060bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham ValueAnimator updateAnimator = ValueAnimator.ofFloat(0, 1); 5070bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham updateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 5080bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham @Override 5090bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham public void onAnimationUpdate(ValueAnimator animation) { 5100bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham dispatchOnLauncherTransitionStep(fromView, animation.getAnimatedFraction()); 5110bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham dispatchOnLauncherTransitionStep(toView, animation.getAnimatedFraction()); 5120bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham } 5130bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham }); 5140bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham return updateAnimator; 5150bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham } 5160bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 5170bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham /** 5186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the apps view. 519b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 520006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState, 521645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final Workspace.State toWorkspaceState, final boolean animated, int type, 5222a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 5235f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung AllAppsContainerView appsView = mLauncher.getAppsView(); 5240ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal // No alpha anim from all apps 5250ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) { 526b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 527b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewStartFinalRadius() { 5282e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; 529b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return allAppsButtonSize / 2; 530b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 531b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 532b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 533b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View revealView, final View allAppsButtonView) { 534b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 535b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationStart(Animator animation) { 536b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // We set the alpha instead of visibility to ensure that the focus does not 537b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // get taken from the all apps view 538b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.VISIBLE); 539b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(0f); 540b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 541b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 542b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 543b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 544b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 545b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Show the all apps button, and focus it 546b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(1f); 547b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 548b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 549b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 5508fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 5518fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 552aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 5538fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 554b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 555ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating to spring loaded mode from all apps 556191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState, 557bb011dad4e69bec027be1e00d573a3095b318b43Sunny Goyal mLauncher.getStartViewForAllAppsRevealAnimation(), appsView, 558645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, type, onCompleteRunnable, cb); 559b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 560b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 561b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 5626d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the widgets view. 563b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 564006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState, 5656d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Workspace.State toWorkspaceState, final boolean animated, 5662a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 5674cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song final WidgetsContainerView widgetsView = mLauncher.getWidgetsView(); 5680ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = 5690ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS) { 570b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 571b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 57298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View revealView, final View widgetsButtonView) { 573b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 574b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 575b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 576b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 577b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 578b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 579b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 5808fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 5818fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 582aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 5838fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 584b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 585191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimationToWorkspaceFromOverlay( 5860ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal fromWorkspaceState, toWorkspaceState, 5877c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal mLauncher.getWidgetsButton(), widgetsView, 588645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, CIRCULAR_REVEAL, onCompleteRunnable, cb); 589b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 590b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 591b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 5926d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from another workspace state, e.g. normal to overview. 5936d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham */ 5946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham private void startAnimationToNewWorkspaceState(final Workspace.State fromWorkspaceState, 5956d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Workspace.State toWorkspaceState, final boolean animated, 5966d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Runnable onCompleteRunnable) { 5976d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final View fromWorkspace = mLauncher.getWorkspace(); 5986d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final HashMap<View, Integer> layerViews = new HashMap<>(); 5996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 6006d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final int revealDuration = mLauncher.getResources() 6016d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham .getInteger(R.integer.config_overlayRevealTime); 6026d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6036d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Cancel the current animation 6046d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham cancelAnimation(); 6056d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 606f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages; 607f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham 6087c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal playCommonTransitionAnimations(toWorkspaceState, fromWorkspace, null, 60961d9e78f23efcf43be1945d4233780ac89db99d9Winson animated, animated, animation, layerViews); 6106d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6116d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (animated) { 612f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible); 6136d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6146d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final AnimatorSet stateAnimation = animation; 6156d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Runnable startAnimRunnable = new Runnable() { 6166d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham @TargetApi(Build.VERSION_CODES.LOLLIPOP) 6176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham public void run() { 6186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Check that mCurrentAnimation hasn't changed while 6196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // we waited for a layout/draw pass 6206d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (mCurrentAnimation != stateAnimation) 6216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham return; 6226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionStart(fromWorkspace, animated, true); 6246d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6256d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Enable all necessary layers 6266d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham for (View v : layerViews.keySet()) { 6276d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 6286d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 6296d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6306d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 6316d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.buildLayer(); 6326d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6336d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6346d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham stateAnimation.start(); 6356d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6366d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham }; 6376d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham animation.addListener(new AnimatorListenerAdapter() { 6386d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham @Override 6396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham public void onAnimationEnd(Animator animation) { 6406d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true); 6416d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6426d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Run any queued runnables 6436d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (onCompleteRunnable != null) { 6446d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham onCompleteRunnable.run(); 6456d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6466d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6476d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Disable all necessary layers 6486d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham for (View v : layerViews.keySet()) { 6496d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 6506d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.setLayerType(View.LAYER_TYPE_NONE, null); 6516d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6526d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6536d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6546d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // This can hold unnecessary references to views. 6556d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham cleanupAnimation(); 6566d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6576d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham }); 6586d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham fromWorkspace.post(startAnimRunnable); 6596d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham mCurrentAnimation = animation; 6606d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else /* if (!animated) */ { 661f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible); 6626d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionStart(fromWorkspace, animated, true); 6636d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true); 6646d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6656d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Run any queued runnables 6666d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (onCompleteRunnable != null) { 6676d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham onCompleteRunnable.run(); 6686d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6696d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6706d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham mCurrentAnimation = null; 6716d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6726d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6736d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6746d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham /** 675b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to the workspace. 676b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 677191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song private void startAnimationToWorkspaceFromOverlay( 6780ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 6790ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View buttonView, final BaseContainerView fromView, 680645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final boolean animated, int animType, final Runnable onCompleteRunnable, 681006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final PrivateTransitionCallbacks pCb) { 682006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 683b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 6849fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal final boolean material = Utilities.ATLEAST_LOLLIPOP; 6855f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 686e3876e8dd0a6b6948c5365af9f88709301bbb536Hyunyoung Song final int revealDurationSlide = res.getInteger(R.integer.config_overlaySlideRevealTime); 687b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final int itemsAlphaStagger = 6885f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung res.getInteger(R.integer.config_overlayItemsAlphaStagger); 689b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 690b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View toView = mLauncher.getWorkspace(); 69161d9e78f23efcf43be1945d4233780ac89db99d9Winson final View revealView = fromView.getRevealView(); 69261d9e78f23efcf43be1945d4233780ac89db99d9Winson final View contentView = fromView.getContentView(); 693b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 694b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final HashMap<View, Integer> layerViews = new HashMap<>(); 695b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 696b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 69798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 698b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 699b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 700b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 701b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 702f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages; 703f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham 704a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song playCommonTransitionAnimations(toWorkspaceState, fromView, toView, 70561d9e78f23efcf43be1945d4233780ac89db99d9Winson animated, initialized, animation, layerViews); 70674b5af35291f620d2f09f313f2e9bd9f817b9d27Hyunyoung Song if (!animated || !initialized) { 707ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && 708ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song fromWorkspaceState == Workspace.State.NORMAL_HIDDEN) { 7097ccc4625e38b8107cd1882272aec36967874a5ccHyunyoung Song mAllAppsController.finishPullDown(); 710b11ae50fcb2bb07ee77645fdacdf90f67f58dae4Hyunyoung Song } 711645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song fromView.setVisibility(View.GONE); 712645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible); 713645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(fromView, animated, true); 714645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, true); 715645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible); 716645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(toView, animated, true); 717645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, true); 718645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 7190bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 720645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Run any queued runnables 721645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (onCompleteRunnable != null) { 722645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song onCompleteRunnable.run(); 723645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 724191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song return; 725645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 726645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (animType == CIRCULAR_REVEAL) { 727b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // hideAppsCustomizeHelper is called in some cases when it is already hidden 728b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // don't perform all these no-op animations. In particularly, this was causing 729b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // the all-apps button to pop in and out. 730b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (fromView.getVisibility() == View.VISIBLE) { 731b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 732b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 733f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 734b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(1f); 736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0); 737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(revealView, BUILD_AND_SET_LAYER); 738b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 739b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 740b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 742b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 74398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, 74498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song buttonView, null); 74598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 74698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 747b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 748b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 750b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // The vertical motion of the apps panel should be delayed by one frame 753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // from the conceal animation in order to give the right feel. We correspondingly 754b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // shorten the duration so that the slide and conceal end at the same time. 755b745afbdd75157c73d581b345118cdaff99e912dWinson Chung TimeInterpolator decelerateInterpolator = material ? 756b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new LogDecelerateInterpolator(100, 0) : 757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new DecelerateInterpolator(1f); 7581558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY", 759b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 760b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY); 761b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 762b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setInterpolator(decelerateInterpolator); 763006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftY); 764b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 7651558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX", 766b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToXDrift); 767b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY); 768b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 769b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setInterpolator(decelerateInterpolator); 770006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftX); 771b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 772b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup animation for the reveal panel alpha 773b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha = !material ? 0f : 7740ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal pCb.materialRevealViewFinalAlpha; 775b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (revealViewToAlpha != 1f) { 7761558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha", 777b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1f, revealViewToAlpha); 778b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setDuration(material ? revealDuration : 150); 779b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY); 780b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setInterpolator(decelerateInterpolator); 781006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlpha); 782b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 783b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 784b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 785b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(contentView, BUILD_AND_SET_LAYER); 786b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 787b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 7881558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 789b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 790b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 791b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY); 792b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(decelerateInterpolator); 793b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 794006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 795b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 796b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1f); 7971558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f); 798b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(100); 799b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(decelerateInterpolator); 800006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 801b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 8023f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham // Invalidate the scrim throughout the animation to ensure the highlight 8033f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham // cutout is correct throughout. 8043f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham ValueAnimator invalidateScrim = ValueAnimator.ofFloat(0f, 1f); 8053f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham invalidateScrim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 8063f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham @Override 8073f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham public void onAnimationUpdate(ValueAnimator animation) { 8083f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham mLauncher.getDragLayer().invalidateScrim(); 8093f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham } 8103f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham }); 8113f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham animation.play(invalidateScrim); 8123f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham 813b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 814b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Animate the all apps button 815b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float finalRadius = pCb.getMaterialRevealViewStartFinalRadius(); 816b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = 81798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView); 8188f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2, 8198f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham revealRadius, finalRadius).createRevealAnimator(revealView); 820b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 821b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 822b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setStartDelay(itemsAlphaStagger); 823b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 824b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 825b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 826006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(reveal); 827b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 828b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 829b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 830f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible); 831f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible); 832a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham 833006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 834b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 835b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 836b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.setVisibility(View.GONE); 837b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, true); 838b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, true); 839b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 840b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Run any queued runnables 841b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (onCompleteRunnable != null) { 842b745afbdd75157c73d581b345118cdaff99e912dWinson Chung onCompleteRunnable.run(); 843b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 844b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 845b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Disable all necessary layers 846b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 847b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 848b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_NONE, null); 849b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 850b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 851b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 852b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Reset page transforms 853b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (contentView != null) { 854b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationX(0); 855b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 856b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1); 857b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 858b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 859b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 860006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 86176648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 862b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 863b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 864b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 865006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet stateAnimation = animation; 866b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Runnable startAnimRunnable = new Runnable() { 867756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal @TargetApi(Build.VERSION_CODES.LOLLIPOP) 868b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void run() { 869006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Check that mCurrentAnimation hasn't changed while 870b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // we waited for a layout/draw pass 871006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != stateAnimation) 872b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return; 873006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 874b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 875b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 876b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 877b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Enable all necessary layers 878b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 879b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 880b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 881b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 882756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 883b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.buildLayer(); 884b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 885b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 886006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung stateAnimation.start(); 887b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 888b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 889191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song mCurrentAnimation = animation; 890b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.post(startAnimRunnable); 891645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } else if (animType == PULLUP) { 89261d9e78f23efcf43be1945d4233780ac89db99d9Winson // We are animating the content view alpha, so ensure we have a layer for it 89361d9e78f23efcf43be1945d4233780ac89db99d9Winson layerViews.put(contentView, BUILD_AND_SET_LAYER); 89461d9e78f23efcf43be1945d4233780ac89db99d9Winson 895645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animation.addListener(new AnimatorListenerAdapter() { 896eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song boolean canceled = false; 897645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song @Override 898eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song public void onAnimationCancel(Animator animation) { 899eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song canceled = true; 900645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 901b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 902645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song @Override 903645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void onAnimationEnd(Animator animation) { 904eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song if (canceled) return; 9059dcf0a3ef7595f58aedec7773e7bc3b9075fb3caHyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, true); 9069dcf0a3ef7595f58aedec7773e7bc3b9075fb3caHyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, true); 907645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Run any queued runnables 908645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (onCompleteRunnable != null) { 909645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song onCompleteRunnable.run(); 910645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 91161d9e78f23efcf43be1945d4233780ac89db99d9Winson 91261d9e78f23efcf43be1945d4233780ac89db99d9Winson // Disable all necessary layers 91361d9e78f23efcf43be1945d4233780ac89db99d9Winson for (View v : layerViews.keySet()) { 91461d9e78f23efcf43be1945d4233780ac89db99d9Winson if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 91561d9e78f23efcf43be1945d4233780ac89db99d9Winson v.setLayerType(View.LAYER_TYPE_NONE, null); 91661d9e78f23efcf43be1945d4233780ac89db99d9Winson } 91761d9e78f23efcf43be1945d4233780ac89db99d9Winson } 91861d9e78f23efcf43be1945d4233780ac89db99d9Winson 919645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song cleanupAnimation(); 920645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 921645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 922eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song 923645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }); 924191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song boolean shouldPost = mAllAppsController.animateToWorkspace(animation, revealDurationSlide); 925eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song 926eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song // Dispatch the prepare transition signal 9276f02f2ffb4b3cec91891bed9a0c179d2c913d27eSunny Goyal dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible); 9286f02f2ffb4b3cec91891bed9a0c179d2c913d27eSunny Goyal dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible); 929645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 930645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final AnimatorSet stateAnimation = animation; 931645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final Runnable startAnimRunnable = new Runnable() { 932645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void run() { 933645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Check that mCurrentAnimation hasn't changed while 934645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // we waited for a layout/draw pass 935645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (mCurrentAnimation != stateAnimation) 936645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return; 93761d9e78f23efcf43be1945d4233780ac89db99d9Winson 938645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(fromView, animated, false); 939645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(toView, animated, false); 940645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 94161d9e78f23efcf43be1945d4233780ac89db99d9Winson // Enable all necessary layers 94261d9e78f23efcf43be1945d4233780ac89db99d9Winson for (View v : layerViews.keySet()) { 94361d9e78f23efcf43be1945d4233780ac89db99d9Winson if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 94461d9e78f23efcf43be1945d4233780ac89db99d9Winson v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 94561d9e78f23efcf43be1945d4233780ac89db99d9Winson } 94661d9e78f23efcf43be1945d4233780ac89db99d9Winson if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 94761d9e78f23efcf43be1945d4233780ac89db99d9Winson v.buildLayer(); 94861d9e78f23efcf43be1945d4233780ac89db99d9Winson } 94961d9e78f23efcf43be1945d4233780ac89db99d9Winson } 95061d9e78f23efcf43be1945d4233780ac89db99d9Winson 951645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Focus the new view 952645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.requestFocus(); 953645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song stateAnimation.start(); 954645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 955645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }; 956191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song mCurrentAnimation = animation; 957191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song if (shouldPost) { 958191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song fromView.post(startAnimRunnable); 959191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } else { 960191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimRunnable.run(); 961191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } 962b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 963191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song return; 964b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 965b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 966006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung /** 967b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the prepare-transition event to suitable views. 968b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 969f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham void dispatchOnLauncherTransitionPrepare(View v, boolean animated, 970f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham boolean multiplePagesVisible) { 971b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 972b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated, 973f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham multiplePagesVisible); 974b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 975b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 976b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 977b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 978b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the start-transition event to suitable views. 979b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 980b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) { 981b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 982b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated, 983b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 984b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 985b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 986b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Update the workspace transition step as well 987b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStep(v, 0f); 988b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 989b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 990b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 991b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the step-transition event to suitable views. 992b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 993b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionStep(View v, float t) { 994b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 995b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t); 996b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 997b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 998b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 999b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 1000b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the end-transition event to suitable views. 1001b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 1002b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) { 1003b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 1004b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated, 1005b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 1006b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 1007b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1008b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Update the workspace transition step as well 1009b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStep(v, 1f); 1010b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 1011b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1012b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 1013b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Cancels the current animation. 1014b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 1015b745afbdd75157c73d581b345118cdaff99e912dWinson Chung private void cancelAnimation() { 1016006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != null) { 1017006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.setDuration(0); 1018006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.cancel(); 1019006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 1020b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 1021b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 1022006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 1023d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal @Thunk void cleanupAnimation() { 1024006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 1025006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung } 10261558893b873cd55b2df779f594f1de3c370d3328Adam Cohen} 1027