LauncherStateTransitionAnimation.java revision f3e35d93318190f995e6a0fc9d0441ac844b67e4
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 269645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Show the content view 270645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song contentView.setVisibility(View.VISIBLE); 271645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 272645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(fromView, animated, false); 273645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(fromView, animated, false); 274645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, false); 275645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(toView, animated, false); 276645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(toView, animated, false); 277645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, false); 278645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 279191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song return; 280645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 281645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (animType == CIRCULAR_REVEAL) { 282b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the reveal view animation 2830ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View revealView = toView.getRevealView(); 2840ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 285b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 286b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 287f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 289b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(0f); 290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0f); 291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationX(0f); 292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 294b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha; 295b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 297b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 2980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace( 2990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal revealView, buttonView, null); 3000ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal revealViewToAlpha = pCb.materialRevealViewFinalAlpha; 30198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 30298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToAlpha = 0f; 305b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 308b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 309b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the animators 310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelAlpha = 3115d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f); 312b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftY = 3135d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0); 314b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftX = 3155d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0); 316b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView, 317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha, panelDriftY, panelDriftX); 318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setDuration(revealDuration); 319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Play the animation 322b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(revealView, BUILD_AND_SET_LAYER); 323006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlphaAndDrift); 324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setVisibility(View.VISIBLE); 327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(0f); 328b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(revealViewToYDrift); 329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(contentView, BUILD_AND_SET_LAYER); 330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift, 0); 334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration); 335b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 336b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger); 337006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 338b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f); 340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(revealDuration); 341b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setStartDelay(itemsAlphaStagger); 343006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 344b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float startRadius = pCb.getMaterialRevealViewStartFinalRadius(); 347b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener( 34898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealView, buttonView); 3498f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2, 3508f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham startRadius, revealRadius).createRevealAnimator(revealView); 351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 354b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 355b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 356006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(reveal); 357b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 359006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 360b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 361b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, false); 363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, false); 364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 367b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Disable all necessary layers 369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_NONE, null); 372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 375b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 376006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 37776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 378b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 380b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Dispatch the prepare transition signal 383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, false); 384b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, false); 385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 386006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet stateAnimation = animation; 387b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Runnable startAnimRunnable = new Runnable() { 388b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void run() { 389006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Check that mCurrentAnimation hasn't changed while 390b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // we waited for a layout/draw pass 391006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != stateAnimation) 392b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return; 393b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 394b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 395b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 396b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Enable all necessary layers 397b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 398b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 399b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 400b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 401756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 402b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.buildLayer(); 403b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 404b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 405b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 406b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Focus the new view 407b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.requestFocus(); 408b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 409006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung stateAnimation.start(); 410b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 411b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 412b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.bringToFront(); 413b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setVisibility(View.VISIBLE); 414b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.post(startAnimRunnable); 415191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song mCurrentAnimation = animation; 416645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } else if (animType == PULLUP) { 41761d9e78f23efcf43be1945d4233780ac89db99d9Winson // We are animating the content view alpha, so ensure we have a layer for it 41861d9e78f23efcf43be1945d4233780ac89db99d9Winson layerViews.put(contentView, BUILD_AND_SET_LAYER); 41961d9e78f23efcf43be1945d4233780ac89db99d9Winson 420645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animation.addListener(new AnimatorListenerAdapter() { 421191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song @Override 422191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song public void onAnimationEnd(Animator animation) { 423191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, false); 424191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, false); 425191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song 426191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song // Disable all necessary layers 427191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song for (View v : layerViews.keySet()) { 428191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 429191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song v.setLayerType(View.LAYER_TYPE_NONE, null); 430191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } 431191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } 432191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song 433191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song cleanupAnimation(); 434191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song pCb.onTransitionComplete(); 435191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } 436645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }); 437191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song boolean shouldPost = mAllAppsController.animateToAllApps(animation, revealDurationSlide); 438b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 439b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, false); 440b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, false); 441006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 442645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final AnimatorSet stateAnimation = animation; 443645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final Runnable startAnimRunnable = new Runnable() { 444645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void run() { 445645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Check that mCurrentAnimation hasn't changed while 446645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // we waited for a layout/draw pass 447645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (mCurrentAnimation != stateAnimation) 448645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return; 44961d9e78f23efcf43be1945d4233780ac89db99d9Winson 450645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(fromView, animated, false); 451645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(toView, animated, false); 452645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 45361d9e78f23efcf43be1945d4233780ac89db99d9Winson // Enable all necessary layers 45461d9e78f23efcf43be1945d4233780ac89db99d9Winson for (View v : layerViews.keySet()) { 45561d9e78f23efcf43be1945d4233780ac89db99d9Winson if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 45661d9e78f23efcf43be1945d4233780ac89db99d9Winson v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 45761d9e78f23efcf43be1945d4233780ac89db99d9Winson } 45861d9e78f23efcf43be1945d4233780ac89db99d9Winson if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 45961d9e78f23efcf43be1945d4233780ac89db99d9Winson v.buildLayer(); 46061d9e78f23efcf43be1945d4233780ac89db99d9Winson } 46161d9e78f23efcf43be1945d4233780ac89db99d9Winson } 46261d9e78f23efcf43be1945d4233780ac89db99d9Winson 463645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.requestFocus(); 464645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song stateAnimation.start(); 465645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 466645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }; 467191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song mCurrentAnimation = animation; 468191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song if (shouldPost) { 469191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song toView.post(startAnimRunnable); 470191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } else { 471191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimRunnable.run(); 472191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } 473b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 474b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 475b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 476b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 477685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham * Plays animations used by various transitions. 478685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham */ 4797c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal private void playCommonTransitionAnimations( 4807c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal Workspace.State toWorkspaceState, View fromView, View toView, 48161d9e78f23efcf43be1945d4233780ac89db99d9Winson boolean animated, boolean initialized, AnimatorSet animation, 482685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham HashMap<View, Integer> layerViews) { 483685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Create the workspace animation. 484685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // NOTE: this call apparently also sets the state for the workspace if !animated 485685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState, 486685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animated, layerViews); 487685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 488685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham if (animated && initialized) { 489685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Play the workspace animation 490685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham if (workspaceAnim != null) { 491685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animation.play(workspaceAnim); 492685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 493685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Dispatch onLauncherTransitionStep() as the animation interpolates. 494685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animation.play(dispatchOnLauncherTransitionStepAnim(fromView, toView)); 495685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 496685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 497685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 498685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham /** 4990bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * Returns an Animator that calls {@link #dispatchOnLauncherTransitionStep(View, float)} on 5000bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * {@param fromView} and {@param toView} as the animation interpolates. 5010bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * 5020bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * This is a bit hacky: we create a dummy ValueAnimator just for the AnimatorUpdateListener. 5030bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham */ 5040bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham private Animator dispatchOnLauncherTransitionStepAnim(final View fromView, final View toView) { 5050bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham ValueAnimator updateAnimator = ValueAnimator.ofFloat(0, 1); 5060bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham updateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 5070bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham @Override 5080bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham public void onAnimationUpdate(ValueAnimator animation) { 5090bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham dispatchOnLauncherTransitionStep(fromView, animation.getAnimatedFraction()); 5100bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham dispatchOnLauncherTransitionStep(toView, animation.getAnimatedFraction()); 5110bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham } 5120bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham }); 5130bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham return updateAnimator; 5140bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham } 5150bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 5160bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham /** 5176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the apps view. 518b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 519006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState, 520645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final Workspace.State toWorkspaceState, final boolean animated, int type, 5212a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 5225f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung AllAppsContainerView appsView = mLauncher.getAppsView(); 5230ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal // No alpha anim from all apps 5240ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) { 525b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 526b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewStartFinalRadius() { 5272e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; 528b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return allAppsButtonSize / 2; 529b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 530b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 531b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 532b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View revealView, final View allAppsButtonView) { 533b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 534b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationStart(Animator animation) { 535b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // We set the alpha instead of visibility to ensure that the focus does not 536b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // get taken from the all apps view 537b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.VISIBLE); 538b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(0f); 539b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 540b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 541b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 542b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 543b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 544b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Show the all apps button, and focus it 545b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(1f); 546b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 547b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 548b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 5498fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 5508fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 551aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 5528fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 553b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 554ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating to spring loaded mode from all apps 555191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState, 556bb011dad4e69bec027be1e00d573a3095b318b43Sunny Goyal mLauncher.getStartViewForAllAppsRevealAnimation(), appsView, 557645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, type, onCompleteRunnable, cb); 558b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 559b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 560b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 5616d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the widgets view. 562b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 563006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState, 5646d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Workspace.State toWorkspaceState, final boolean animated, 5652a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 5664cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song final WidgetsContainerView widgetsView = mLauncher.getWidgetsView(); 5670ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = 5680ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS) { 569b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 570b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 57198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View revealView, final View widgetsButtonView) { 572b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 573b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 574b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 575b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 576b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 577b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 578b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 5798fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 5808fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 581aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 5828fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 583b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 584191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimationToWorkspaceFromOverlay( 5850ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal fromWorkspaceState, toWorkspaceState, 5867c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal mLauncher.getWidgetsButton(), widgetsView, 587645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, CIRCULAR_REVEAL, onCompleteRunnable, cb); 588b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 589b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 590b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 5916d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from another workspace state, e.g. normal to overview. 5926d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham */ 5936d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham private void startAnimationToNewWorkspaceState(final Workspace.State fromWorkspaceState, 5946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Workspace.State toWorkspaceState, final boolean animated, 5956d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Runnable onCompleteRunnable) { 5966d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final View fromWorkspace = mLauncher.getWorkspace(); 5976d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final HashMap<View, Integer> layerViews = new HashMap<>(); 5986d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 5996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final int revealDuration = mLauncher.getResources() 6006d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham .getInteger(R.integer.config_overlayRevealTime); 6016d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6026d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Cancel the current animation 6036d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham cancelAnimation(); 6046d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 605f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages; 606f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham 6077c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal playCommonTransitionAnimations(toWorkspaceState, fromWorkspace, null, 60861d9e78f23efcf43be1945d4233780ac89db99d9Winson animated, animated, animation, layerViews); 6096d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 610f3e35d93318190f995e6a0fc9d0441ac844b67e4Jon Miranda mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 611f3e35d93318190f995e6a0fc9d0441ac844b67e4Jon Miranda 6126d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (animated) { 613f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible); 6146d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6156d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final AnimatorSet stateAnimation = animation; 6166d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Runnable startAnimRunnable = new Runnable() { 6176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham @TargetApi(Build.VERSION_CODES.LOLLIPOP) 6186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham public void run() { 6196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Check that mCurrentAnimation hasn't changed while 6206d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // we waited for a layout/draw pass 6216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (mCurrentAnimation != stateAnimation) 6226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham return; 6236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6246d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionStart(fromWorkspace, animated, true); 6256d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6266d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Enable all necessary layers 6276d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham for (View v : layerViews.keySet()) { 6286d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 6296d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 6306d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6316d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 6326d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.buildLayer(); 6336d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6346d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6356d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham stateAnimation.start(); 6366d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6376d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham }; 6386d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham animation.addListener(new AnimatorListenerAdapter() { 6396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham @Override 6406d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham public void onAnimationEnd(Animator animation) { 6416d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true); 6426d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6436d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Run any queued runnables 6446d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (onCompleteRunnable != null) { 6456d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham onCompleteRunnable.run(); 6466d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6476d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6486d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Disable all necessary layers 6496d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham for (View v : layerViews.keySet()) { 6506d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 6516d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.setLayerType(View.LAYER_TYPE_NONE, null); 6526d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6536d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6546d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6556d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // This can hold unnecessary references to views. 6566d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham cleanupAnimation(); 6576d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6586d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham }); 6596d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham fromWorkspace.post(startAnimRunnable); 6606d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham mCurrentAnimation = animation; 6616d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else /* if (!animated) */ { 662f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible); 6636d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionStart(fromWorkspace, animated, true); 6646d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true); 6656d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6666d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Run any queued runnables 6676d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (onCompleteRunnable != null) { 6686d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham onCompleteRunnable.run(); 6696d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6706d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6716d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham mCurrentAnimation = null; 6726d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6736d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6746d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6756d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham /** 676b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to the workspace. 677b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 678191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song private void startAnimationToWorkspaceFromOverlay( 6790ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 6800ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View buttonView, final BaseContainerView fromView, 681645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final boolean animated, int animType, final Runnable onCompleteRunnable, 682006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final PrivateTransitionCallbacks pCb) { 683006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 684b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 6859fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal final boolean material = Utilities.ATLEAST_LOLLIPOP; 6865f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 687e3876e8dd0a6b6948c5365af9f88709301bbb536Hyunyoung Song final int revealDurationSlide = res.getInteger(R.integer.config_overlaySlideRevealTime); 688b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final int itemsAlphaStagger = 6895f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung res.getInteger(R.integer.config_overlayItemsAlphaStagger); 690b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 691b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View toView = mLauncher.getWorkspace(); 69261d9e78f23efcf43be1945d4233780ac89db99d9Winson final View revealView = fromView.getRevealView(); 69361d9e78f23efcf43be1945d4233780ac89db99d9Winson final View contentView = fromView.getContentView(); 694b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 695b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final HashMap<View, Integer> layerViews = new HashMap<>(); 696b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 697b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 69898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 699b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 700b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 701b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 702b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 703f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages; 704f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham 705a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song playCommonTransitionAnimations(toWorkspaceState, fromView, toView, 70661d9e78f23efcf43be1945d4233780ac89db99d9Winson animated, initialized, animation, layerViews); 70774b5af35291f620d2f09f313f2e9bd9f817b9d27Hyunyoung Song if (!animated || !initialized) { 708ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && 709ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song fromWorkspaceState == Workspace.State.NORMAL_HIDDEN) { 7107ccc4625e38b8107cd1882272aec36967874a5ccHyunyoung Song mAllAppsController.finishPullDown(); 711b11ae50fcb2bb07ee77645fdacdf90f67f58dae4Hyunyoung Song } 712645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song fromView.setVisibility(View.GONE); 713645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible); 714645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(fromView, animated, true); 715645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, true); 716645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible); 717645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(toView, animated, true); 718645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, true); 719645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 7200bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 721645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Run any queued runnables 722645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (onCompleteRunnable != null) { 723645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song onCompleteRunnable.run(); 724645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 725191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song return; 726645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 727645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (animType == CIRCULAR_REVEAL) { 728b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // hideAppsCustomizeHelper is called in some cases when it is already hidden 729b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // don't perform all these no-op animations. In particularly, this was causing 730b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // the all-apps button to pop in and out. 731b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (fromView.getVisibility() == View.VISIBLE) { 732b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 733b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 734f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(1f); 737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0); 738b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(revealView, BUILD_AND_SET_LAYER); 739b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 740b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 742b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 743b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 74498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, 74598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song buttonView, null); 74698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 74798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 748b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 750b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // The vertical motion of the apps panel should be delayed by one frame 754b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // from the conceal animation in order to give the right feel. We correspondingly 755b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // shorten the duration so that the slide and conceal end at the same time. 756b745afbdd75157c73d581b345118cdaff99e912dWinson Chung TimeInterpolator decelerateInterpolator = material ? 757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new LogDecelerateInterpolator(100, 0) : 758b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new DecelerateInterpolator(1f); 7591558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY", 760b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 761b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY); 762b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 763b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setInterpolator(decelerateInterpolator); 764006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftY); 765b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 7661558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX", 767b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToXDrift); 768b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY); 769b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 770b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setInterpolator(decelerateInterpolator); 771006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftX); 772b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 773b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup animation for the reveal panel alpha 774b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha = !material ? 0f : 7750ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal pCb.materialRevealViewFinalAlpha; 776b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (revealViewToAlpha != 1f) { 7771558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha", 778b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1f, revealViewToAlpha); 779b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setDuration(material ? revealDuration : 150); 780b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY); 781b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setInterpolator(decelerateInterpolator); 782006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlpha); 783b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 784b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 785b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 786b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(contentView, BUILD_AND_SET_LAYER); 787b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 788b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 7891558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 790b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 791b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 792b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY); 793b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(decelerateInterpolator); 794b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 795006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 796b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 797b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1f); 7981558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f); 799b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(100); 800b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(decelerateInterpolator); 801006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 802b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 8033f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham // Invalidate the scrim throughout the animation to ensure the highlight 8043f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham // cutout is correct throughout. 8053f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham ValueAnimator invalidateScrim = ValueAnimator.ofFloat(0f, 1f); 8063f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham invalidateScrim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 8073f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham @Override 8083f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham public void onAnimationUpdate(ValueAnimator animation) { 8093f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham mLauncher.getDragLayer().invalidateScrim(); 8103f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham } 8113f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham }); 8123f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham animation.play(invalidateScrim); 8133f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham 814b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 815b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Animate the all apps button 816b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float finalRadius = pCb.getMaterialRevealViewStartFinalRadius(); 817b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = 81898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView); 8198f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2, 8208f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham revealRadius, finalRadius).createRevealAnimator(revealView); 821b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 822b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 823b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setStartDelay(itemsAlphaStagger); 824b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 825b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 826b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 827006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(reveal); 828b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 829b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 830b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 831f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible); 832f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible); 833a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham 834006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 835b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 836b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 837b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.setVisibility(View.GONE); 838b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, true); 839b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, true); 840b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 841b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Run any queued runnables 842b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (onCompleteRunnable != null) { 843b745afbdd75157c73d581b345118cdaff99e912dWinson Chung onCompleteRunnable.run(); 844b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 845b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 846b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Disable all necessary layers 847b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 848b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 849b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_NONE, null); 850b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 851b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 852b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 853b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Reset page transforms 854b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (contentView != null) { 855b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationX(0); 856b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 857b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1); 858b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 859b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 860b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 861006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 86276648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 863b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 864b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 865b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 866006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet stateAnimation = animation; 867b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Runnable startAnimRunnable = new Runnable() { 868756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal @TargetApi(Build.VERSION_CODES.LOLLIPOP) 869b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void run() { 870006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Check that mCurrentAnimation hasn't changed while 871b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // we waited for a layout/draw pass 872006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != stateAnimation) 873b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return; 874006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 875b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 876b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 877b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 878b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Enable all necessary layers 879b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 880b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 881b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 882b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 883756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 884b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.buildLayer(); 885b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 886b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 887006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung stateAnimation.start(); 888b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 889b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 890191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song mCurrentAnimation = animation; 891b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.post(startAnimRunnable); 892645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } else if (animType == PULLUP) { 89361d9e78f23efcf43be1945d4233780ac89db99d9Winson // We are animating the content view alpha, so ensure we have a layer for it 89461d9e78f23efcf43be1945d4233780ac89db99d9Winson layerViews.put(contentView, BUILD_AND_SET_LAYER); 89561d9e78f23efcf43be1945d4233780ac89db99d9Winson 896645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animation.addListener(new AnimatorListenerAdapter() { 897eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song boolean canceled = false; 898645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song @Override 899eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song public void onAnimationCancel(Animator animation) { 900eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song canceled = true; 901645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 902b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 903645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song @Override 904645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void onAnimationEnd(Animator animation) { 905eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song if (canceled) return; 9069dcf0a3ef7595f58aedec7773e7bc3b9075fb3caHyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, true); 9079dcf0a3ef7595f58aedec7773e7bc3b9075fb3caHyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, true); 908645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Run any queued runnables 909645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (onCompleteRunnable != null) { 910645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song onCompleteRunnable.run(); 911645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 91261d9e78f23efcf43be1945d4233780ac89db99d9Winson 91361d9e78f23efcf43be1945d4233780ac89db99d9Winson // Disable all necessary layers 91461d9e78f23efcf43be1945d4233780ac89db99d9Winson for (View v : layerViews.keySet()) { 91561d9e78f23efcf43be1945d4233780ac89db99d9Winson if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 91661d9e78f23efcf43be1945d4233780ac89db99d9Winson v.setLayerType(View.LAYER_TYPE_NONE, null); 91761d9e78f23efcf43be1945d4233780ac89db99d9Winson } 91861d9e78f23efcf43be1945d4233780ac89db99d9Winson } 91961d9e78f23efcf43be1945d4233780ac89db99d9Winson 920645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song cleanupAnimation(); 921645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 922645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 923eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song 924645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }); 925191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song boolean shouldPost = mAllAppsController.animateToWorkspace(animation, revealDurationSlide); 926eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song 927eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song // Dispatch the prepare transition signal 9286f02f2ffb4b3cec91891bed9a0c179d2c913d27eSunny Goyal dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible); 9296f02f2ffb4b3cec91891bed9a0c179d2c913d27eSunny Goyal dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible); 930645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 931645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final AnimatorSet stateAnimation = animation; 932645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final Runnable startAnimRunnable = new Runnable() { 933645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void run() { 934645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Check that mCurrentAnimation hasn't changed while 935645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // we waited for a layout/draw pass 936645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (mCurrentAnimation != stateAnimation) 937645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return; 93861d9e78f23efcf43be1945d4233780ac89db99d9Winson 939645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(fromView, animated, false); 940645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(toView, animated, false); 941645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 94261d9e78f23efcf43be1945d4233780ac89db99d9Winson // Enable all necessary layers 94361d9e78f23efcf43be1945d4233780ac89db99d9Winson for (View v : layerViews.keySet()) { 94461d9e78f23efcf43be1945d4233780ac89db99d9Winson if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 94561d9e78f23efcf43be1945d4233780ac89db99d9Winson v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 94661d9e78f23efcf43be1945d4233780ac89db99d9Winson } 94761d9e78f23efcf43be1945d4233780ac89db99d9Winson if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 94861d9e78f23efcf43be1945d4233780ac89db99d9Winson v.buildLayer(); 94961d9e78f23efcf43be1945d4233780ac89db99d9Winson } 95061d9e78f23efcf43be1945d4233780ac89db99d9Winson } 95161d9e78f23efcf43be1945d4233780ac89db99d9Winson 952645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Focus the new view 953645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.requestFocus(); 954645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song stateAnimation.start(); 955645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 956645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }; 957191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song mCurrentAnimation = animation; 958191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song if (shouldPost) { 959191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song fromView.post(startAnimRunnable); 960191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } else { 961191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song startAnimRunnable.run(); 962191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song } 963b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 964191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song return; 965b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 966b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 967006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung /** 968b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the prepare-transition event to suitable views. 969b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 970f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham void dispatchOnLauncherTransitionPrepare(View v, boolean animated, 971f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham boolean multiplePagesVisible) { 972b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 973b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated, 974f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham multiplePagesVisible); 975b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 976b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 977b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 978b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 979b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the start-transition event to suitable views. 980b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 981b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) { 982b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 983b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated, 984b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 985b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 986b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 987b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Update the workspace transition step as well 988b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStep(v, 0f); 989b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 990b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 991b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 992b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the step-transition event to suitable views. 993b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 994b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionStep(View v, float t) { 995b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 996b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t); 997b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 998b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 999b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1000b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 1001b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the end-transition event to suitable views. 1002b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 1003b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) { 1004b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 1005b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated, 1006b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 1007b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 1008b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1009b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Update the workspace transition step as well 1010b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStep(v, 1f); 1011b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 1012b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1013b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 1014b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Cancels the current animation. 1015b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 1016b745afbdd75157c73d581b345118cdaff99e912dWinson Chung private void cancelAnimation() { 1017006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != null) { 1018006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.setDuration(0); 1019006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.cancel(); 1020006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 1021b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 1022b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 1023006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 1024d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal @Thunk void cleanupAnimation() { 1025006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 1026006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung } 10271558893b873cd55b2df779f594f1de3c370d3328Adam Cohen} 1028