LauncherStateTransitionAnimation.java revision 8f58e61d02fcb0ca90a2803e76a8792ec2c1f99a
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 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 2510ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View contentView = toView.getContentView(); 252a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song playCommonTransitionAnimations(toWorkspaceState, fromView, toView, 253a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song animated, initialized, animation, revealDuration, layerViews); 254645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (!animated || !initialized) { 255ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && 256ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song toWorkspaceState == Workspace.State.NORMAL_HIDDEN) { 257ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song mAllAppsController.finishPullUp(); 258ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song } 259645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setTranslationX(0.0f); 260645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setTranslationY(0.0f); 261645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setScaleX(1.0f); 262645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setScaleY(1.0f); 263645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setAlpha(1.0f); 264645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.setVisibility(View.VISIBLE); 265645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.bringToFront(); 266645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 267645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Show the content view 268645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song contentView.setVisibility(View.VISIBLE); 269645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 270645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(fromView, animated, false); 271645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(fromView, animated, false); 272645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, false); 273645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(toView, animated, false); 274645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(toView, animated, false); 275645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, false); 276645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 277645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 278645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return null; 279645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 280645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (animType == CIRCULAR_REVEAL) { 281b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the reveal view animation 2820ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View revealView = toView.getRevealView(); 2830ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 284b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 285b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 286f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 287b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(0f); 289b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0f); 290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationX(0f); 291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha; 294b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 295b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 2970ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace( 2980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal revealView, buttonView, null); 2990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal revealViewToAlpha = pCb.materialRevealViewFinalAlpha; 30098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 30198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 302b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToAlpha = 0f; 304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 305b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 308b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the animators 309b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelAlpha = 3105d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f); 311b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftY = 3125d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0); 313b745afbdd75157c73d581b345118cdaff99e912dWinson Chung PropertyValuesHolder panelDriftX = 3145d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0); 315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView, 316b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha, panelDriftY, panelDriftX); 317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setDuration(revealDuration); 318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Play the animation 321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(revealView, BUILD_AND_SET_LAYER); 322006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlphaAndDrift); 323b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setVisibility(View.VISIBLE); 326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(0f); 327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(revealViewToYDrift); 328b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(contentView, BUILD_AND_SET_LAYER); 329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift, 0); 333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration); 334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0)); 335b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger); 336006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 337b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 338b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f); 339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(revealDuration); 340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 341b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setStartDelay(itemsAlphaStagger); 342006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 343b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 344b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float startRadius = pCb.getMaterialRevealViewStartFinalRadius(); 346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener( 34798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealView, buttonView); 3488f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2, 3498f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham startRadius, revealRadius).createRevealAnimator(revealView); 350b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 354b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 355006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(reveal); 356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 357b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 358006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 360b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 361b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, false); 362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, false); 363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 367b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Disable all necessary layers 368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_NONE, null); 371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 375006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 37676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 377b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 378b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 380b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Dispatch the prepare transition signal 382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(fromView, animated, false); 383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionPrepare(toView, animated, false); 384b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 385006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet stateAnimation = animation; 386b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Runnable startAnimRunnable = new Runnable() { 387b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void run() { 388006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Check that mCurrentAnimation hasn't changed while 389b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // we waited for a layout/draw pass 390006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != stateAnimation) 391b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return; 392b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 393b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 394b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 395b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Enable all necessary layers 396b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 397b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 398b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 399b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 400756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 401b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.buildLayer(); 402b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 403b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 404b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 405b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Focus the new view 406b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.requestFocus(); 407b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 408006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung stateAnimation.start(); 409b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 410b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 411b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.bringToFront(); 412b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.setVisibility(View.VISIBLE); 413b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toView.post(startAnimRunnable); 414006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 415006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung return animation; 416645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } else if (animType == PULLUP) { 417645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animation.addListener(new AnimatorListenerAdapter() { 418645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song @Override 419645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void onAnimationEnd(Animator animation) { 420645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, false); 421645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, false); 422645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song cleanupAnimation(); 423645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 424645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 425645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }); 426eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song mAllAppsController.animateToAllApps(animation, revealDuration, false); 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 if (animated && initialized) { 464685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Play the workspace animation 465685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham if (workspaceAnim != null) { 466685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animation.play(workspaceAnim); 467685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 468685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham // Dispatch onLauncherTransitionStep() as the animation interpolates. 469685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham animation.play(dispatchOnLauncherTransitionStepAnim(fromView, toView)); 470685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 471685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham } 472685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham 473685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham /** 4740bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * Returns an Animator that calls {@link #dispatchOnLauncherTransitionStep(View, float)} on 4750bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * {@param fromView} and {@param toView} as the animation interpolates. 4760bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * 4770bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham * This is a bit hacky: we create a dummy ValueAnimator just for the AnimatorUpdateListener. 4780bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham */ 4790bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham private Animator dispatchOnLauncherTransitionStepAnim(final View fromView, final View toView) { 4800bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham ValueAnimator updateAnimator = ValueAnimator.ofFloat(0, 1); 4810bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham updateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 4820bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham @Override 4830bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham public void onAnimationUpdate(ValueAnimator animation) { 4840bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham dispatchOnLauncherTransitionStep(fromView, animation.getAnimatedFraction()); 4850bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham dispatchOnLauncherTransitionStep(toView, animation.getAnimatedFraction()); 4860bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham } 4870bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham }); 4880bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham return updateAnimator; 4890bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham } 4900bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 4910bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham /** 4926d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the apps view. 493b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 494006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState, 495645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final Workspace.State toWorkspaceState, final boolean animated, int type, 4962a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 4975f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung AllAppsContainerView appsView = mLauncher.getAppsView(); 4980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal // No alpha anim from all apps 4990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) { 500b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 501b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float getMaterialRevealViewStartFinalRadius() { 5022e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize; 503b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return allAppsButtonSize / 2; 504b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 505b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 506b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 507b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View revealView, final View allAppsButtonView) { 508b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 509b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationStart(Animator animation) { 510b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // We set the alpha instead of visibility to ensure that the focus does not 511b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // get taken from the all apps view 512b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setVisibility(View.VISIBLE); 513b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(0f); 514b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 515b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 516b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 517b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 518b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 519b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Show the all apps button, and focus it 520b745afbdd75157c73d581b345118cdaff99e912dWinson Chung allAppsButtonView.setAlpha(1f); 521b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 522b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 523b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 5248fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 5258fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 526aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 5278fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 528b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 529ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung // Only animate the search bar if animating to spring loaded mode from all apps 530006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState, 531bb011dad4e69bec027be1e00d573a3095b318b43Sunny Goyal mLauncher.getStartViewForAllAppsRevealAnimation(), appsView, 532645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, type, onCompleteRunnable, cb); 533b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 534b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 535b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 5366d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from the widgets view. 537b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 538006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState, 5396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Workspace.State toWorkspaceState, final boolean animated, 5402a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson final Runnable onCompleteRunnable) { 5414cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song final WidgetsContainerView widgetsView = mLauncher.getWidgetsView(); 5420ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal PrivateTransitionCallbacks cb = 5430ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS) { 544b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 545b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener( 54698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song final View revealView, final View widgetsButtonView) { 547b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return new AnimatorListenerAdapter() { 548b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 549b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Hide the reveal view 550b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.INVISIBLE); 551b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 552b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 553b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 5548fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song @Override 5558fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song void onTransitionComplete() { 556aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); 5578fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song } 558b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 5590ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal mCurrentAnimation = startAnimationToWorkspaceFromOverlay( 5600ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal fromWorkspaceState, toWorkspaceState, 5617c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal mLauncher.getWidgetsButton(), widgetsView, 562645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animated, CIRCULAR_REVEAL, onCompleteRunnable, cb); 563b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 564b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 565b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 5666d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham * Starts an animation to the workspace from another workspace state, e.g. normal to overview. 5676d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham */ 5686d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham private void startAnimationToNewWorkspaceState(final Workspace.State fromWorkspaceState, 5696d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Workspace.State toWorkspaceState, final boolean animated, 5706d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Runnable onCompleteRunnable) { 5716d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final View fromWorkspace = mLauncher.getWorkspace(); 5726d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final HashMap<View, Integer> layerViews = new HashMap<>(); 5736d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 5746d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final int revealDuration = mLauncher.getResources() 5756d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham .getInteger(R.integer.config_overlayRevealTime); 5766d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5776d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Cancel the current animation 5786d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham cancelAnimation(); 5796d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 580f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages; 581f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham 5827c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal playCommonTransitionAnimations(toWorkspaceState, fromWorkspace, null, 5837c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal animated, animated, animation, revealDuration, layerViews); 5846d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5856d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (animated) { 586f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible); 5876d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5886d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final AnimatorSet stateAnimation = animation; 5896d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham final Runnable startAnimRunnable = new Runnable() { 5906d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham @TargetApi(Build.VERSION_CODES.LOLLIPOP) 5916d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham public void run() { 5926d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Check that mCurrentAnimation hasn't changed while 5936d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // we waited for a layout/draw pass 5946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (mCurrentAnimation != stateAnimation) 5956d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham return; 5966d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5976d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionStart(fromWorkspace, animated, true); 5986d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 5996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Enable all necessary layers 6006d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham for (View v : layerViews.keySet()) { 6016d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 6026d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 6036d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6046d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 6056d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.buildLayer(); 6066d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6076d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6086d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham stateAnimation.start(); 6096d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6106d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham }; 6116d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham animation.addListener(new AnimatorListenerAdapter() { 6126d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham @Override 6136d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham public void onAnimationEnd(Animator animation) { 6146d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true); 6156d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6166d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Run any queued runnables 6176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (onCompleteRunnable != null) { 6186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham onCompleteRunnable.run(); 6196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6206d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Disable all necessary layers 6226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham for (View v : layerViews.keySet()) { 6236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 6246d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham v.setLayerType(View.LAYER_TYPE_NONE, null); 6256d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6266d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6276d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6286d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // This can hold unnecessary references to views. 6296d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham cleanupAnimation(); 6306d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6316d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham }); 6326d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham fromWorkspace.post(startAnimRunnable); 6336d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham mCurrentAnimation = animation; 6346d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } else /* if (!animated) */ { 635f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible); 6366d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionStart(fromWorkspace, animated, true); 6376d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true); 6386d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham // Run any queued runnables 6406d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham if (onCompleteRunnable != null) { 6416d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham onCompleteRunnable.run(); 6426d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6436d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6446d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham mCurrentAnimation = null; 6456d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6466d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham } 6476d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham 6486d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham /** 649b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Creates and starts a new animation to the workspace. 650b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 6510ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private AnimatorSet startAnimationToWorkspaceFromOverlay( 6520ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, 6530ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View buttonView, final BaseContainerView fromView, 654645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final boolean animated, int animType, final Runnable onCompleteRunnable, 655006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final PrivateTransitionCallbacks pCb) { 656006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); 657b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Resources res = mLauncher.getResources(); 6589fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal final boolean material = Utilities.ATLEAST_LOLLIPOP; 6595f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime); 660b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final int itemsAlphaStagger = 6615f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung res.getInteger(R.integer.config_overlayItemsAlphaStagger); 662b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 663b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final View toView = mLauncher.getWorkspace(); 664b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 665b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final HashMap<View, Integer> layerViews = new HashMap<>(); 666b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 667b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // If for some reason our views aren't initialized, don't animate 66898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song boolean initialized = buttonView != null; 669b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 670b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Cancel the current animation 671b745afbdd75157c73d581b345118cdaff99e912dWinson Chung cancelAnimation(); 672b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 673f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages; 674f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham 675a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song playCommonTransitionAnimations(toWorkspaceState, fromView, toView, 676a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song animated, initialized, animation, revealDuration, layerViews); 67774b5af35291f620d2f09f313f2e9bd9f817b9d27Hyunyoung Song if (!animated || !initialized) { 678ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && 679ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song fromWorkspaceState == Workspace.State.NORMAL_HIDDEN) { 680a30b51ceb29e179caf7f441763ffeb6bfd336998Peter Schiller mAllAppsController.finishPullDown(false); 681b11ae50fcb2bb07ee77645fdacdf90f67f58dae4Hyunyoung Song } 682645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song fromView.setVisibility(View.GONE); 683645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible); 684645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(fromView, animated, true); 685645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, true); 686645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible); 687645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(toView, animated, true); 688645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, true); 689645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 6900bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 691645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Run any queued runnables 692645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (onCompleteRunnable != null) { 693645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song onCompleteRunnable.run(); 694645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 695645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return null; 696645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 697645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (animType == CIRCULAR_REVEAL) { 6980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View revealView = fromView.getRevealView(); 6990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal final View contentView = fromView.getContentView(); 7000bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham 701b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // hideAppsCustomizeHelper is called in some cases when it is already hidden 702b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // don't perform all these no-op animations. In particularly, this was causing 703b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // the all-apps button to pop in and out. 704b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (fromView.getVisibility() == View.VISIBLE) { 705b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int width = revealView.getMeasuredWidth(); 706b745afbdd75157c73d581b345118cdaff99e912dWinson Chung int height = revealView.getMeasuredHeight(); 707f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float revealRadius = (float) Math.hypot(width / 2, height / 2); 708b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setVisibility(View.VISIBLE); 709b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setAlpha(1f); 710b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealView.setTranslationY(0); 711b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(revealView, BUILD_AND_SET_LAYER); 712b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 713b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Calculate the final animation values 714b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToXDrift; 715b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToYDrift; 716b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 71798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, 71898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song buttonView, null); 71998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToYDrift = buttonViewToPanelDelta[1]; 72098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song revealViewToXDrift = buttonViewToPanelDelta[0]; 721b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } else { 722b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToYDrift = 2 * height / 3; 723b745afbdd75157c73d581b345118cdaff99e912dWinson Chung revealViewToXDrift = 0; 724b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 725b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 726b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // The vertical motion of the apps panel should be delayed by one frame 727b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // from the conceal animation in order to give the right feel. We correspondingly 728b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // shorten the duration so that the slide and conceal end at the same time. 729b745afbdd75157c73d581b345118cdaff99e912dWinson Chung TimeInterpolator decelerateInterpolator = material ? 730b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new LogDecelerateInterpolator(100, 0) : 731b745afbdd75157c73d581b345118cdaff99e912dWinson Chung new DecelerateInterpolator(1f); 7321558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY", 733b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 734b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY); 735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftY.setInterpolator(decelerateInterpolator); 737006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftY); 738b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 7391558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX", 740b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToXDrift); 741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY); 742b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 743b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelDriftX.setInterpolator(decelerateInterpolator); 744006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelDriftX); 745b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 746b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup animation for the reveal panel alpha 747b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final float revealViewToAlpha = !material ? 0f : 7480ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal pCb.materialRevealViewFinalAlpha; 749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (revealViewToAlpha != 1f) { 7501558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha", 751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 1f, revealViewToAlpha); 752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setDuration(material ? revealDuration : 150); 753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY); 754b745afbdd75157c73d581b345118cdaff99e912dWinson Chung panelAlpha.setInterpolator(decelerateInterpolator); 755006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(panelAlpha); 756b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 758b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Setup the animation for the content view 759b745afbdd75157c73d581b345118cdaff99e912dWinson Chung layerViews.put(contentView, BUILD_AND_SET_LAYER); 760b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 761b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Create the individual animators 7621558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY", 763b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 0, revealViewToYDrift); 764b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 765b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY); 766b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setInterpolator(decelerateInterpolator); 767b745afbdd75157c73d581b345118cdaff99e912dWinson Chung pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY); 768006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(pageDrift); 769b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 770b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1f); 7711558893b873cd55b2df779f594f1de3c370d3328Adam Cohen ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f); 772b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setDuration(100); 773b745afbdd75157c73d581b345118cdaff99e912dWinson Chung itemsAlpha.setInterpolator(decelerateInterpolator); 774006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(itemsAlpha); 775b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 7763f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham // Invalidate the scrim throughout the animation to ensure the highlight 7773f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham // cutout is correct throughout. 7783f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham ValueAnimator invalidateScrim = ValueAnimator.ofFloat(0f, 1f); 7793f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham invalidateScrim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 7803f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham @Override 7813f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham public void onAnimationUpdate(ValueAnimator animation) { 7823f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham mLauncher.getDragLayer().invalidateScrim(); 7833f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham } 7843f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham }); 7853f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham animation.play(invalidateScrim); 7863f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham 787b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (material) { 788b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Animate the all apps button 789b745afbdd75157c73d581b345118cdaff99e912dWinson Chung float finalRadius = pCb.getMaterialRevealViewStartFinalRadius(); 790b745afbdd75157c73d581b345118cdaff99e912dWinson Chung AnimatorListenerAdapter listener = 79198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView); 7928f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2, 7938f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham revealRadius, finalRadius).createRevealAnimator(revealView); 794b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 795b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setDuration(revealDuration); 796b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.setStartDelay(itemsAlphaStagger); 797b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (listener != null) { 798b745afbdd75157c73d581b345118cdaff99e912dWinson Chung reveal.addListener(listener); 799b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 800006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.play(reveal); 801b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 802b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 803b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 804f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible); 805f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible); 806a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham 807006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung animation.addListener(new AnimatorListenerAdapter() { 808b745afbdd75157c73d581b345118cdaff99e912dWinson Chung @Override 809b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void onAnimationEnd(Animator animation) { 810b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.setVisibility(View.GONE); 811b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(fromView, animated, true); 812b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionEnd(toView, animated, true); 813b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 814b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Run any queued runnables 815b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (onCompleteRunnable != null) { 816b745afbdd75157c73d581b345118cdaff99e912dWinson Chung onCompleteRunnable.run(); 817b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 818b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 819b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Disable all necessary layers 820b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 821b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 822b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_NONE, null); 823b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 824b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 825b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 826b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Reset page transforms 827b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (contentView != null) { 828b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationX(0); 829b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setTranslationY(0); 830b745afbdd75157c73d581b345118cdaff99e912dWinson Chung contentView.setAlpha(1); 831b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 832b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 833b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // This can hold unnecessary references to views. 834006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung cleanupAnimation(); 83576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung pCb.onTransitionComplete(); 836b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 837b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }); 838b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 839006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung final AnimatorSet stateAnimation = animation; 840b745afbdd75157c73d581b345118cdaff99e912dWinson Chung final Runnable startAnimRunnable = new Runnable() { 841756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal @TargetApi(Build.VERSION_CODES.LOLLIPOP) 842b745afbdd75157c73d581b345118cdaff99e912dWinson Chung public void run() { 843006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung // Check that mCurrentAnimation hasn't changed while 844b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // we waited for a layout/draw pass 845006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != stateAnimation) 846b745afbdd75157c73d581b345118cdaff99e912dWinson Chung return; 847006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 848b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(fromView, animated, false); 849b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStart(toView, animated, false); 850b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 851b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Enable all necessary layers 852b745afbdd75157c73d581b345118cdaff99e912dWinson Chung for (View v : layerViews.keySet()) { 853b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (layerViews.get(v) == BUILD_AND_SET_LAYER) { 854b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 855b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 856756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) { 857b745afbdd75157c73d581b345118cdaff99e912dWinson Chung v.buildLayer(); 858b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 859b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 860006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung stateAnimation.start(); 861b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 862b745afbdd75157c73d581b345118cdaff99e912dWinson Chung }; 863b745afbdd75157c73d581b345118cdaff99e912dWinson Chung fromView.post(startAnimRunnable); 864006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 865006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung return animation; 866645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } else if (animType == PULLUP) { 867645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song animation.addListener(new AnimatorListenerAdapter() { 868eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song boolean canceled = false; 869645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song @Override 870eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song public void onAnimationCancel(Animator animation) { 871eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song canceled = true; 872645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 873b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 874645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song @Override 875645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void onAnimationEnd(Animator animation) { 876eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song if (canceled) return; 877eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song dispatchOnLauncherTransitionEnd(fromView, animated, false); 878eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song dispatchOnLauncherTransitionEnd(toView, animated, false); 879645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Run any queued runnables 880645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (onCompleteRunnable != null) { 881645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song onCompleteRunnable.run(); 882645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 883645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song cleanupAnimation(); 884645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song pCb.onTransitionComplete(); 885645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 886eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song 887645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }); 888eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song mAllAppsController.animateToWorkspace(animation, revealDuration, false); 889eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song 890eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song // Dispatch the prepare transition signal 8916f02f2ffb4b3cec91891bed9a0c179d2c913d27eSunny Goyal dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible); 8926f02f2ffb4b3cec91891bed9a0c179d2c913d27eSunny Goyal dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible); 893645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 894645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final AnimatorSet stateAnimation = animation; 895645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song final Runnable startAnimRunnable = new Runnable() { 896645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void run() { 897645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Check that mCurrentAnimation hasn't changed while 898645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // we waited for a layout/draw pass 899645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (mCurrentAnimation != stateAnimation) 900645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return; 901645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(fromView, animated, false); 902645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song dispatchOnLauncherTransitionStart(toView, animated, false); 903645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 904645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Focus the new view 905645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song toView.requestFocus(); 906645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song stateAnimation.start(); 907645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 908645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song }; 909645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song fromView.post(startAnimRunnable); 910645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return animation; 911b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 912645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return null; 913b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 914b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 915006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung /** 916b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the prepare-transition event to suitable views. 917b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 918f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham void dispatchOnLauncherTransitionPrepare(View v, boolean animated, 919f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham boolean multiplePagesVisible) { 920b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 921b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated, 922f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham multiplePagesVisible); 923b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 924b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 925b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 926b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 927b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the start-transition event to suitable views. 928b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 929b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) { 930b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 931b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated, 932b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 933b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 934b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 935b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Update the workspace transition step as well 936b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStep(v, 0f); 937b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 938b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 939b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 940b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the step-transition event to suitable views. 941b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 942b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionStep(View v, float t) { 943b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 944b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t); 945b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 946b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 947b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 948b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 949b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Dispatches the end-transition event to suitable views. 950b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 951b745afbdd75157c73d581b345118cdaff99e912dWinson Chung void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) { 952b745afbdd75157c73d581b345118cdaff99e912dWinson Chung if (v instanceof LauncherTransitionable) { 953b745afbdd75157c73d581b345118cdaff99e912dWinson Chung ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated, 954b745afbdd75157c73d581b345118cdaff99e912dWinson Chung toWorkspace); 955b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 956b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 957b745afbdd75157c73d581b345118cdaff99e912dWinson Chung // Update the workspace transition step as well 958b745afbdd75157c73d581b345118cdaff99e912dWinson Chung dispatchOnLauncherTransitionStep(v, 1f); 959b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 960b745afbdd75157c73d581b345118cdaff99e912dWinson Chung 961b745afbdd75157c73d581b345118cdaff99e912dWinson Chung /** 962b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Cancels the current animation. 963b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */ 964b745afbdd75157c73d581b345118cdaff99e912dWinson Chung private void cancelAnimation() { 965006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung if (mCurrentAnimation != null) { 966006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.setDuration(0); 967006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation.cancel(); 968006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 969b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 970b745afbdd75157c73d581b345118cdaff99e912dWinson Chung } 971006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung 972d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal @Thunk void cleanupAnimation() { 973006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung mCurrentAnimation = null; 974006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung } 9751558893b873cd55b2df779f594f1de3c370d3328Adam Cohen} 976