LauncherStateTransitionAnimation.java revision 645764e3e5fa34d9adcddfc722d726b76f048306
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; 38091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 395d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyalimport com.android.launcher3.util.UiThreadCircularReveal; 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(); 14598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View buttonView = mLauncher.getAllAppsButton(); 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 177006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = 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(); 188006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = 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 210b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED) { 211645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song int animType = CIRCULAR_REVEAL; 212645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) { 213645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animType = PULLUP; 214645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 2152a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson startAnimationToWorkspaceFromAllApps(fromWorkspaceState, toWorkspaceState, 216645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, animType, onCompleteRunnable); 2176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else if (fromState == Launcher.State.WIDGETS || 2186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham fromState == Launcher.State.WIDGETS_SPRING_LOADED) { 2192a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson startAnimationToWorkspaceFromWidgets(fromWorkspaceState, toWorkspaceState, 220dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung animated, onCompleteRunnable); 2216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else { 2226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham startAnimationToNewWorkspaceState(fromWorkspaceState, toWorkspaceState, 2236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham animated, onCompleteRunnable); 224b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 225b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 226b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 227b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 228b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to a particular overlay view. 229b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 2307066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal @SuppressLint("NewApi") 2310ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private AnimatorSet startAnimationToOverlay( 2320ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 2330ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View buttonView, final BaseContainerView toView, 234645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final boolean animated, int animType, final PrivateTransitionCallbacks pCb) { 235006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 236b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 2379fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal final boolean material = Utilities.ATLEAST_LOLLIPOP; 2385f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 2390ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final int itemsAlphaStagger = res.getInteger(R.integer.config_overlayItemsAlphaStagger); 240b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 241b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View fromView = mLauncher.getWorkspace(); 242b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 243b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final HashMap<View, Integer> layerViews = new HashMap<>(); 244b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 245b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 24698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 247b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 248b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 249b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 250b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 251645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (!FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) { 252645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song playCommonTransitionAnimations(toWorkspaceState, fromView, toView, 253645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, initialized, animation, revealDuration, layerViews); 254645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 2550ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View contentView = toView.getContentView(); 2560bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 257645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (!animated || !initialized) { 258645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setTranslationX(0.0f); 259645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setTranslationY(0.0f); 260645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setScaleX(1.0f); 261645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setScaleY(1.0f); 262645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setAlpha(1.0f); 263645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setVisibility(View.VISIBLE); 264645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.bringToFront(); 265645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 266645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Show the content view 267645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song contentView.setVisibility(View.VISIBLE); 268645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 269645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(fromView, animated, false); 270645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(fromView, animated, false); 271645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, false); 272645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(toView, animated, false); 273645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(toView, animated, false); 274645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, false); 275645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 276645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 277645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return null; 278645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 279645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (animType == CIRCULAR_REVEAL) { 280b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the reveal view animation 2810ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View revealView = toView.getRevealView(); 2820ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 283b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 284b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 285f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 286b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 287b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(0f); 288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0f); 289b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationX(0f); 290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha; 293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 294b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 295b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 2960ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace( 2970ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal revealView, buttonView, null); 2980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal revealViewToAlpha = pCb.materialRevealViewFinalAlpha; 29998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 30098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 301b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 302b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToAlpha = 0f; 303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 305b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the animators 308b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelAlpha = 3095d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f); 310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftY = 3115d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0); 312b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftX = 3135d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0); 314b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView, 315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha, panelDriftY, panelDriftX); 316b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setDuration(revealDuration); 317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Play the animation 320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(revealView, BUILD_AND_SET_LAYER); 321006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlphaAndDrift); 322b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 323b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setVisibility(View.VISIBLE); 325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(0f); 326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(revealViewToYDrift); 327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(contentView, BUILD_AND_SET_LAYER); 328b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift, 0); 332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration); 333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger); 335006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 336b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 337b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f); 338b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(revealDuration); 339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setStartDelay(itemsAlphaStagger); 341006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 343b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 344b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float startRadius = pCb.getMaterialRevealViewStartFinalRadius(); 345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener( 34698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealView, buttonView); 3471558893b873cd55b2df779f594f1de3c370d3328Adam Cohen Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2, 348b745afbdd75157c73d581b345118cdaff99e912dWinson Chung height / 2, startRadius, revealRadius); 349b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 350b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 354006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(reveal); 355b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 357006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 360b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, false); 361b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, false); 362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Disable all necessary layers 367b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_NONE, null); 370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 374006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 37576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 376b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 377b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 378b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 380b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Dispatch the prepare transition signal 381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, false); 382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, false); 383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 384006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet stateAnimation = animation; 385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Runnable startAnimRunnable = new Runnable() { 386b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void run() { 387006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Check that mCurrentAnimation hasn't changed while 388b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // we waited for a layout/draw pass 389006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != stateAnimation) 390b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return; 391b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 392b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 393b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 394b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Enable all necessary layers 395b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 396b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 397b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 398b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 399756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 400b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.buildLayer(); 401b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 402b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 403b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 404b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Focus the new view 405b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.requestFocus(); 406b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 407006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung stateAnimation.start(); 408b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 409b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 410b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.bringToFront(); 411b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setVisibility(View.VISIBLE); 412b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.post(startAnimRunnable); 413006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 414006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung return animation; 415645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } else if (animType == PULLUP) { 416645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animation.addListener(new AnimatorListenerAdapter() { 417645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song @Override 418645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void onAnimationEnd(Animator animation) { 419645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, false); 420645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, false); 421645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song cleanupAnimation(); 422645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 423645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 424b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 425645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }); 426645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song mAllAppsController.animateToAllApps(animation); 427b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 428b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, false); 429b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, false); 430006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 431645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final AnimatorSet stateAnimation = animation; 432645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final Runnable startAnimRunnable = new Runnable() { 433645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void run() { 434645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Check that mCurrentAnimation hasn't changed while 435645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // we waited for a layout/draw pass 436645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (mCurrentAnimation != stateAnimation) 437645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return; 438645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(fromView, animated, false); 439645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(toView, animated, false); 440645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 441645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.requestFocus(); 442645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song stateAnimation.start(); 443645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 444645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }; 445645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.post(startAnimRunnable); 446645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return animation; 447b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 448645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return null; 449b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 450b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 451b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 452685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham * Plays animations used by various transitions. 453685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham */ 4547c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal private void playCommonTransitionAnimations( 4557c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal Workspace.State toWorkspaceState, View fromView, View toView, 456685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham boolean animated, boolean initialized, AnimatorSet animation, int revealDuration, 457685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham HashMap<View, Integer> layerViews) { 458685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Create the workspace animation. 459685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // NOTE: this call apparently also sets the state for the workspace if !animated 460685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState, 461685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animated, layerViews); 462685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 463685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Animate the search bar 4647c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal final SearchDropTargetBar.State toSearchBarState = 4652e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal toWorkspaceState.searchDropTargetBarState; 4667c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState, 4677c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal animated ? revealDuration : 0, animation); 468685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 469685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham if (animated && initialized) { 470685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Play the workspace animation 471685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham if (workspaceAnim != null) { 472685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animation.play(workspaceAnim); 473685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 474685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Dispatch onLauncherTransitionStep() as the animation interpolates. 475685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animation.play(dispatchOnLauncherTransitionStepAnim(fromView, toView)); 476685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 477685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 478685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 479685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham /** 4800bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * Returns an Animator that calls {@link #dispatchOnLauncherTransitionStep(View, float)} on 4810bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * {@param fromView} and {@param toView} as the animation interpolates. 4820bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * 4830bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * This is a bit hacky: we create a dummy ValueAnimator just for the AnimatorUpdateListener. 4840bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham */ 4850bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham private Animator dispatchOnLauncherTransitionStepAnim(final View fromView, final View toView) { 4860bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham ValueAnimator updateAnimator = ValueAnimator.ofFloat(0, 1); 4870bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham updateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 4880bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham @Override 4890bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham public void onAnimationUpdate(ValueAnimator animation) { 4900bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham dispatchOnLauncherTransitionStep(fromView, animation.getAnimatedFraction()); 4910bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham dispatchOnLauncherTransitionStep(toView, animation.getAnimatedFraction()); 4920bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham } 4930bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham }); 4940bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham return updateAnimator; 4950bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham } 4960bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 4970bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham /** 4986d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the apps view. 499b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 500006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState, 501645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final Workspace.State toWorkspaceState, final boolean animated, int type, 5022a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 5035f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung AllAppsContainerView appsView = mLauncher.getAppsView(); 5040ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal // No alpha anim from all apps 5050ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) { 506b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 507b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewStartFinalRadius() { 5082e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; 509b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return allAppsButtonSize / 2; 510b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 511b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 512b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 513b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View revealView, final View allAppsButtonView) { 514b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 515b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationStart(Animator animation) { 516b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // We set the alpha instead of visibility to ensure that the focus does not 517b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // get taken from the all apps view 518b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.VISIBLE); 519b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(0f); 520b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 521b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 522b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 523b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 524b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 525b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Show the all apps button, and focus it 526b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(1f); 527b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 528b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 529b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 5308fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 5318fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 532aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 5338fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 534b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 535ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating to spring loaded mode from all apps 536006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState, 5377c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal mLauncher.getAllAppsButton(), appsView, 538645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, type, onCompleteRunnable, cb); 539b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 540b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 541b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 5426d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the widgets view. 543b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 544006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState, 5456d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Workspace.State toWorkspaceState, final boolean animated, 5462a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 5474cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song final WidgetsContainerView widgetsView = mLauncher.getWidgetsView(); 5480ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = 5490ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS) { 550b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 551b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 55298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View revealView, final View widgetsButtonView) { 553b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 554b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 555b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 556b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 557b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 558b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 559b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 5608fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 5618fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 562aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 5638fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 564b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 5650ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal mCurrentAnimation = startAnimationToWorkspaceFromOverlay( 5660ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal fromWorkspaceState, toWorkspaceState, 5677c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal mLauncher.getWidgetsButton(), widgetsView, 568645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, CIRCULAR_REVEAL, onCompleteRunnable, cb); 569b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 570b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 571b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 5726d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from another workspace state, e.g. normal to overview. 5736d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham */ 5746d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham private void startAnimationToNewWorkspaceState(final Workspace.State fromWorkspaceState, 5756d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Workspace.State toWorkspaceState, final boolean animated, 5766d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Runnable onCompleteRunnable) { 5776d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final View fromWorkspace = mLauncher.getWorkspace(); 5786d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final HashMap<View, Integer> layerViews = new HashMap<>(); 5796d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 5806d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final int revealDuration = mLauncher.getResources() 5816d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham .getInteger(R.integer.config_overlayRevealTime); 5826d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5836d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Cancel the current animation 5846d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham cancelAnimation(); 5856d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 586f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages; 587f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham 5887c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal playCommonTransitionAnimations(toWorkspaceState, fromWorkspace, null, 5897c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal animated, animated, animation, revealDuration, layerViews); 5906d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5916d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (animated) { 592f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible); 5936d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final AnimatorSet stateAnimation = animation; 5956d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Runnable startAnimRunnable = new Runnable() { 5966d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham @TargetApi(Build.VERSION_CODES.LOLLIPOP) 5976d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham public void run() { 5986d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Check that mCurrentAnimation hasn't changed while 5996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // we waited for a layout/draw pass 6006d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (mCurrentAnimation != stateAnimation) 6016d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham return; 6026d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6036d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionStart(fromWorkspace, animated, true); 6046d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6056d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Enable all necessary layers 6066d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham for (View v : layerViews.keySet()) { 6076d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 6086d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 6096d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6106d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 6116d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.buildLayer(); 6126d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6136d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6146d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham stateAnimation.start(); 6156d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6166d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham }; 6176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham animation.addListener(new AnimatorListenerAdapter() { 6186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham @Override 6196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham public void onAnimationEnd(Animator animation) { 6206d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true); 6216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Run any queued runnables 6236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (onCompleteRunnable != null) { 6246d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham onCompleteRunnable.run(); 6256d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6266d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6276d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Disable all necessary layers 6286d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham for (View v : layerViews.keySet()) { 6296d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 6306d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.setLayerType(View.LAYER_TYPE_NONE, null); 6316d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6326d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6336d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6346d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // This can hold unnecessary references to views. 6356d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham cleanupAnimation(); 6366d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6376d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham }); 6386d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham fromWorkspace.post(startAnimRunnable); 6396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham mCurrentAnimation = animation; 6406d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else /* if (!animated) */ { 641f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible); 6426d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionStart(fromWorkspace, animated, true); 6436d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true); 6446d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6456d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Run any queued runnables 6466d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (onCompleteRunnable != null) { 6476d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham onCompleteRunnable.run(); 6486d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6496d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6506d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham mCurrentAnimation = null; 6516d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6526d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6536d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6546d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham /** 655b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to the workspace. 656b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 6570ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private AnimatorSet startAnimationToWorkspaceFromOverlay( 6580ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 6590ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View buttonView, final BaseContainerView fromView, 660645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final boolean animated, int animType, final Runnable onCompleteRunnable, 661006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final PrivateTransitionCallbacks pCb) { 662006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 663b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 6649fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal final boolean material = Utilities.ATLEAST_LOLLIPOP; 6655f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 666b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final int itemsAlphaStagger = 6675f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung res.getInteger(R.integer.config_overlayItemsAlphaStagger); 668b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 669b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View toView = mLauncher.getWorkspace(); 670b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 671b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final HashMap<View, Integer> layerViews = new HashMap<>(); 672b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 673b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 67498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 675b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 676b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 677b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 678b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 679f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages; 680f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham 681645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (!FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) { 682645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song playCommonTransitionAnimations(toWorkspaceState, fromView, toView, 683645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, initialized, animation, revealDuration, layerViews); 684645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 685645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (!animated || !initialized) { 686645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song mAllAppsController.finishPullDown(); 687645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song fromView.setVisibility(View.GONE); 688645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible); 689645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(fromView, animated, true); 690645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, true); 691645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible); 692645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(toView, animated, true); 693645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, true); 694645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 6950bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 696645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Run any queued runnables 697645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (onCompleteRunnable != null) { 698645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song onCompleteRunnable.run(); 699645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 700645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 701645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return null; 702645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 703645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (animType == CIRCULAR_REVEAL) { 7040ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View revealView = fromView.getRevealView(); 7050ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View contentView = fromView.getContentView(); 7060bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 707b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // hideAppsCustomizeHelper is called in some cases when it is already hidden 708b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // don't perform all these no-op animations. In particularly, this was causing 709b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // the all-apps button to pop in and out. 710b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (fromView.getVisibility() == View.VISIBLE) { 711b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 712b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 713f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 714b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 715b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(1f); 716b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0); 717b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(revealView, BUILD_AND_SET_LAYER); 718b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 719b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 720b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 721b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 722b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 72398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, 72498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song buttonView, null); 72598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 72698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 727b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 728b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 729b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 730b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 731b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 732b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // The vertical motion of the apps panel should be delayed by one frame 733b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // from the conceal animation in order to give the right feel. We correspondingly 734b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // shorten the duration so that the slide and conceal end at the same time. 735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung TimeInterpolator decelerateInterpolator = material ? 736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new LogDecelerateInterpolator(100, 0) : 737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new DecelerateInterpolator(1f); 7381558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY", 739b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 740b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY); 741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 742b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setInterpolator(decelerateInterpolator); 743006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftY); 744b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 7451558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX", 746b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToXDrift); 747b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY); 748b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setInterpolator(decelerateInterpolator); 750006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftX); 751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup animation for the reveal panel alpha 753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha = !material ? 0f : 7540ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal pCb.materialRevealViewFinalAlpha; 755b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (revealViewToAlpha != 1f) { 7561558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha", 757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1f, revealViewToAlpha); 758b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setDuration(material ? revealDuration : 150); 759b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY); 760b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setInterpolator(decelerateInterpolator); 761006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlpha); 762b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 763b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 764b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 765b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(contentView, BUILD_AND_SET_LAYER); 766b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 767b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 7681558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 769b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 770b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 771b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY); 772b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(decelerateInterpolator); 773b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 774006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 775b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 776b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1f); 7771558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f); 778b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(100); 779b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(decelerateInterpolator); 780006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 781b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 7823f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham // Invalidate the scrim throughout the animation to ensure the highlight 7833f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham // cutout is correct throughout. 7843f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham ValueAnimator invalidateScrim = ValueAnimator.ofFloat(0f, 1f); 7853f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham invalidateScrim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 7863f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham @Override 7873f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham public void onAnimationUpdate(ValueAnimator animation) { 7883f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham mLauncher.getDragLayer().invalidateScrim(); 7893f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham } 7903f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham }); 7913f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham animation.play(invalidateScrim); 7923f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham 793b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 794b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Animate the all apps button 795b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float finalRadius = pCb.getMaterialRevealViewStartFinalRadius(); 796b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = 79798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView); 7981558893b873cd55b2df779f594f1de3c370d3328Adam Cohen Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2, 7991558893b873cd55b2df779f594f1de3c370d3328Adam Cohen height / 2, revealRadius, finalRadius); 800b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 801b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 802b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setStartDelay(itemsAlphaStagger); 803b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 804b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 805b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 806006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(reveal); 807b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 808b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 809b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 810f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible); 811f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible); 812a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham 813006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 814b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 815b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 816b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.setVisibility(View.GONE); 817b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, true); 818b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, true); 819b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 820b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Run any queued runnables 821b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (onCompleteRunnable != null) { 822b745afbdd75157c73d581b345118cdaff99e912dWinson Chung onCompleteRunnable.run(); 823b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 824b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 825b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Disable all necessary layers 826b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 827b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 828b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_NONE, null); 829b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 830b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 831b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 832b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Reset page transforms 833b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (contentView != null) { 834b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationX(0); 835b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 836b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1); 837b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 838b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 839b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 840006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 84176648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 842b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 843b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 844b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 845006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet stateAnimation = animation; 846b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Runnable startAnimRunnable = new Runnable() { 847756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal @TargetApi(Build.VERSION_CODES.LOLLIPOP) 848b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void run() { 849006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Check that mCurrentAnimation hasn't changed while 850b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // we waited for a layout/draw pass 851006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != stateAnimation) 852b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return; 853006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 854b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 855b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 856b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 857b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Enable all necessary layers 858b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 859b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 860b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 861b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 862756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 863b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.buildLayer(); 864b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 865b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 866006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung stateAnimation.start(); 867b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 868b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 869b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.post(startAnimRunnable); 870006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 871006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung return animation; 872645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } else if (animType == PULLUP) { 873645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animation.addListener(new AnimatorListenerAdapter() { 874645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song @Override 875645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void onAnimationEnd(Animator animation) { 876645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, false); 877645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, false); 878645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song cleanupAnimation(); 879645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 880645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 881b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 882645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }); 883645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song mAllAppsController.animateToWorkspace(animation); 884006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 885645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Dispatch the prepare transition signal 886645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(fromView, animated, false); 887645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(toView, animated, false); 888645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 889645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animation.addListener(new AnimatorListenerAdapter() { 890645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song @Override 891645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void onAnimationEnd(Animator animation) { 892645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, true); 893645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, true); 894645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 895645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Run any queued runnables 896645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (onCompleteRunnable != null) { 897645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song onCompleteRunnable.run(); 898645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 899645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 900645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // This can hold unnecessary references to views. 901645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song cleanupAnimation(); 902645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 903645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 904645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }); 905645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 906645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final AnimatorSet stateAnimation = animation; 907645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final Runnable startAnimRunnable = new Runnable() { 908645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void run() { 909645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Check that mCurrentAnimation hasn't changed while 910645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // we waited for a layout/draw pass 911645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (mCurrentAnimation != stateAnimation) 912645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return; 913645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(fromView, animated, false); 914645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(toView, animated, false); 915645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 916645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Focus the new view 917645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.requestFocus(); 918645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song stateAnimation.start(); 919645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 920645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }; 921645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song fromView.post(startAnimRunnable); 922645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return animation; 923b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 924645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return null; 925b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 926b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 927006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung /** 928b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the prepare-transition event to suitable views. 929b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 930f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham void dispatchOnLauncherTransitionPrepare(View v, boolean animated, 931f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham boolean multiplePagesVisible) { 932b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 933b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated, 934f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham multiplePagesVisible); 935b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 936b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 937b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 938b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 939b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the start-transition event to suitable views. 940b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 941b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) { 942b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 943b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated, 944b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 945b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 946b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 947b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Update the workspace transition step as well 948b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStep(v, 0f); 949b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 950b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 951b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 952b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the step-transition event to suitable views. 953b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 954b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionStep(View v, float t) { 955b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 956b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t); 957b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 958b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 959b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 960b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 961b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the end-transition event to suitable views. 962b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 963b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) { 964b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 965b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated, 966b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 967b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 968b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 969b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Update the workspace transition step as well 970b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStep(v, 1f); 971b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 972b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 973b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 974b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Cancels the current animation. 975b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 976b745afbdd75157c73d581b345118cdaff99e912dWinson Chung private void cancelAnimation() { 977006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != null) { 978006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.setDuration(0); 979006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.cancel(); 980006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 981b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 982b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 983006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 984d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal @Thunk void cleanupAnimation() { 985006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 986006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung } 9871558893b873cd55b2df779f594f1de3c370d3328Adam Cohen} 988