diff options
24 files changed, 520 insertions, 636 deletions
diff --git a/res/values/config.xml b/res/values/config.xml index 27d4655b9..c0bf36038 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -46,20 +46,13 @@ <!-- AllApps & Launcher transitions --> <!-- The alpha of the AppsCustomize bg in spring loaded mode --> - <integer name="config_workspaceScrimAlpha">30</integer> - <integer name="config_allAppsTransitionTime">100</integer> - <integer name="config_overviewTransitionTime">250</integer> + <integer name="config_workspaceScrimAlpha">76</integer> <!-- Out of 100, the percent to shrink the workspace during spring loaded mode. --> <integer name="config_workspaceSpringLoadShrinkPercentage">90</integer> <!-- Out of 100, the percent to shrink the workspace during overview mode. --> <integer name="config_workspaceOverviewShrinkPercentage">70</integer> - <!-- Fade/zoom in/out duration & scale in a Launcher overlay transition. - Note: This should be less than the config_overlayTransitionTime as they happen together. --> - <integer name="config_overlaySlideRevealTime">320</integer> - <integer name="config_overlayTransitionTime">300</integer> - <!-- This constant stores the ratio of the all apps button drawable which is used for internal (baked-in) padding --> <integer name="config_allAppsButtonPaddingPercent">17</integer> diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java index e1b5e2c75..1a1c3198f 100644 --- a/src/com/android/launcher3/ButtonDropTarget.java +++ b/src/com/android/launcher3/ButtonDropTarget.java @@ -16,6 +16,8 @@ package com.android.launcher3; +import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_NEXT_FRAME; + import android.animation.AnimatorSet; import android.animation.FloatArrayEvaluator; import android.animation.ObjectAnimator; @@ -229,7 +231,7 @@ public abstract class ButtonDropTarget extends TextView public void run() { completeDrop(d); mDropTargetBar.onDragEnd(); - mLauncher.exitSpringLoadedDragMode(true, 0); + mLauncher.exitSpringLoadedDragMode(SPRING_LOADED_EXIT_NEXT_FRAME); } }; dragLayer.animateView(d.dragView, from, to, scale, 1f, 1f, 0.1f, 0.1f, diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index d6c8575d6..3643971a4 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -104,8 +104,6 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { private final ArrayList<PreviewBackground> mFolderBackgrounds = new ArrayList<>(); final PreviewBackground mFolderLeaveBehind = new PreviewBackground(); - private float mBackgroundAlpha; - private static final int[] BACKGROUND_STATE_ACTIVE = new int[] { android.R.attr.state_active }; private static final int[] BACKGROUND_STATE_DEFAULT = new int[0]; private final Drawable mBackground; @@ -221,7 +219,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { mBackground = res.getDrawable(R.drawable.bg_celllayout); mBackground.setCallback(this); - mBackground.setAlpha((int) (mBackgroundAlpha * 255)); + mBackground.setAlpha(0); mReorderPreviewAnimationMagnitude = (REORDER_PREVIEW_MAGNITUDE * grid.iconSizePx); @@ -440,7 +438,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { // When we're small, we are either drawn normally or in the "accepts drops" state (during // a drag). However, we also drag the mini hover background *over* one of those two // backgrounds - if (mBackgroundAlpha > 0.0f) { + if (mBackground.getAlpha() > 0) { mBackground.draw(canvas); } @@ -847,15 +845,8 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { return getMeasuredWidth() - getPaddingLeft() - getPaddingRight() - (mCountX * mCellWidth); } - public float getBackgroundAlpha() { - return mBackgroundAlpha; - } - - public void setBackgroundAlpha(float alpha) { - if (mBackgroundAlpha != alpha) { - mBackgroundAlpha = alpha; - mBackground.setAlpha((int) (mBackgroundAlpha * 255)); - } + public Drawable getScrimBackground() { + return mBackground; } @Override diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index bfcd82ace..a80e62b08 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -16,6 +16,9 @@ package com.android.launcher3; +import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_NEXT_FRAME; +import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_SHORT_TIMEOUT; +import static com.android.launcher3.logging.LoggerUtils.newContainerTarget; import static com.android.launcher3.util.RunnableWithId.RUNNABLE_ID_BIND_APPS; import static com.android.launcher3.util.RunnableWithId.RUNNABLE_ID_BIND_WIDGETS; @@ -117,6 +120,7 @@ import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.userevent.nano.LauncherLogProto.Action; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType; +import com.android.launcher3.userevent.nano.LauncherLogProto.Target; import com.android.launcher3.util.ActivityResultInfo; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.ItemInfoMatcher; @@ -205,15 +209,13 @@ public class Launcher extends BaseActivity static final String APPS_VIEW_SHOWN = "launcher.apps_view_shown"; /** The different states that Launcher can be in. */ - enum State { WORKSPACE, WORKSPACE_SPRING_LOADED, APPS, APPS_SPRING_LOADED, - WIDGETS, WIDGETS_SPRING_LOADED } + enum State { WORKSPACE, WORKSPACE_SPRING_LOADED, APPS} @Thunk State mState = State.WORKSPACE; @Thunk LauncherStateTransitionAnimation mStateTransitionAnimation; private boolean mIsSafeModeEnabled; - public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 500; private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500; // How long to wait before the new-shortcut animation automatically pans the workspace @@ -366,9 +368,6 @@ public class Launcher extends BaseActivity mAppWidgetManager = AppWidgetManagerCompat.getInstance(this); mAppWidgetHost = new LauncherAppWidgetHost(this); - if (Utilities.ATLEAST_MARSHMALLOW) { - mAppWidgetHost.addProviderChangeListener(this); - } mAppWidgetHost.startListening(); // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here, @@ -582,8 +581,7 @@ public class Launcher extends BaseActivity Runnable exitSpringLoaded = new Runnable() { @Override public void run() { - exitSpringLoadedDragMode((resultCode != RESULT_CANCELED), - EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT); + exitSpringLoadedDragMode(SPRING_LOADED_EXIT_SHORT_TIMEOUT); } }; @@ -635,7 +633,7 @@ public class Launcher extends BaseActivity final Runnable onComplete = new Runnable() { @Override public void run() { - exitSpringLoadedDragMode(false, 0); + exitSpringLoadedDragMode(SPRING_LOADED_EXIT_NEXT_FRAME); } }; @@ -763,8 +761,7 @@ public class Launcher extends BaseActivity @Override public void run() { completeAddAppWidget(appWidgetId, requestArgs, layout, null); - exitSpringLoadedDragMode((resultCode != RESULT_CANCELED), - EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT); + exitSpringLoadedDragMode(SPRING_LOADED_EXIT_SHORT_TIMEOUT); } }; } else if (resultCode == RESULT_CANCELED) { @@ -1439,8 +1436,9 @@ public class Launcher extends BaseActivity if (topOpenView != null) { topOpenView.logActionCommand(Action.Command.HOME_INTENT); } else if (alreadyOnHome) { - ued.logActionCommand(Action.Command.HOME_INTENT, - mWorkspace.getState().containerType, mWorkspace.getCurrentPage()); + Target target = newContainerTarget(mWorkspace.getState().containerType); + target.pageIndex = mWorkspace.getCurrentPage(); + ued.logActionCommand(Action.Command.HOME_INTENT, target); } // In all these cases, only animate if we're already on home @@ -1714,8 +1712,7 @@ public class Launcher extends BaseActivity @Override public void run() { // Exit spring loaded mode if necessary after adding the widget - exitSpringLoadedDragMode(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT - ); + exitSpringLoadedDragMode(SPRING_LOADED_EXIT_SHORT_TIMEOUT); } }; completeAddAppWidget(appWidgetId, info, boundWidget, addFlowHandler.getProviderInfo(this)); @@ -1899,9 +1896,6 @@ public class Launcher extends BaseActivity } else if (isAppsViewVisible()) { ued.logActionCommand(Action.Command.BACK, ContainerType.ALLAPPS); showWorkspace(true); - } else if (isWidgetsViewVisible()) { - ued.logActionCommand(Action.Command.BACK, ContainerType.WIDGETS); - showOverviewMode(true); } else if (mWorkspace.isInOverviewMode()) { ued.logActionCommand(Action.Command.BACK, ContainerType.OVERVIEW); showWorkspace(true); @@ -2444,10 +2438,6 @@ public class Launcher extends BaseActivity return mState == State.APPS; } - public boolean isWidgetsViewVisible() { - return mState == State.WIDGETS; - } - @Override public void onTrimMemory(int level) { super.onTrimMemory(level); @@ -2546,29 +2536,18 @@ public class Launcher extends BaseActivity /** * Shows the apps view. - */ - public void showAppsView(boolean animated) { - markAppsViewShown(); - showAppsOrWidgets(State.APPS, animated); - } - - /** - * Sets up the transition to show the apps/widgets view. * * @return whether the current from and to state allowed this operation */ // TODO: calling method should use the return value so that when {@code false} is returned // the workspace transition doesn't fall into invalid state. - private boolean showAppsOrWidgets(State toState, boolean animated) { + public boolean showAppsView(boolean animated) { + markAppsViewShown(); + if (!(mState == State.WORKSPACE || - mState == State.APPS_SPRING_LOADED || - mState == State.WIDGETS_SPRING_LOADED || (mState == State.APPS && mAllAppsController.isTransitioning()))) { return false; } - if (toState != State.APPS && toState != State.WIDGETS) { - return false; - } // This is a safe and supported transition to bypass spring_loaded mode. if (mExitSpringLoadedModeRunnable != null) { @@ -2576,14 +2555,10 @@ public class Launcher extends BaseActivity mExitSpringLoadedModeRunnable = null; } - if (toState == State.APPS) { - mStateTransitionAnimation.startAnimationToAllApps(animated); - } else { - mStateTransitionAnimation.startAnimationToWidgets(animated); - } + mStateTransitionAnimation.startAnimationToAllApps(animated); // Change the state *after* we've called all the transition code - setState(toState); + setState(State.APPS); AbstractFloatingView.closeAllOpenViews(this); // Send an accessibility event to announce the context change @@ -2613,12 +2588,11 @@ public class Launcher extends BaseActivity setState(State.WORKSPACE_SPRING_LOADED); } - public void exitSpringLoadedDragMode(final boolean successfulDrop, int delay) { - exitSpringLoadedDragMode(successfulDrop, delay, null); + public void exitSpringLoadedDragMode(int delay) { + exitSpringLoadedDragMode(delay, null); } - public void exitSpringLoadedDragMode(final boolean successfulDrop, int delay, - final Runnable onCompleteRunnable) { + public void exitSpringLoadedDragMode(int delay, final Runnable onCompleteRunnable) { if (!isStateSpringLoaded()) return; // Unlock rotation lock @@ -2634,18 +2608,12 @@ public class Launcher extends BaseActivity mExitSpringLoadedModeRunnable = new Runnable() { @Override public void run() { - if (successfulDrop) { - // TODO(hyunyoungs): verify if this hack is still needed, if not, delete. - // - // Before we show workspace, hide all apps again because - // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should - // clean up our state transition functions - showWorkspace(true, onCompleteRunnable); - } else if (mState == State.APPS_SPRING_LOADED) { - showAppsView(true /* animated */); - } else if (mState == State.WORKSPACE_SPRING_LOADED) { - showWorkspace(true); - } + // TODO(hyunyoungs): verify if this hack is still needed, if not, delete. + // + // Before we show workspace, hide all apps again because + // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should + // clean up our state transition functions + showWorkspace(true, onCompleteRunnable); mExitSpringLoadedModeRunnable = null; } }; @@ -2653,8 +2621,7 @@ public class Launcher extends BaseActivity } boolean isStateSpringLoaded() { - return mState == State.WORKSPACE_SPRING_LOADED || mState == State.APPS_SPRING_LOADED - || mState == State.WIDGETS_SPRING_LOADED; + return mState == State.WORKSPACE_SPRING_LOADED; } @Override @@ -3397,13 +3364,6 @@ public class Launcher extends BaseActivity } } - @Override - public void notifyWidgetProvidersChanged() { - if (mWorkspace.getState().shouldUpdateWidget) { - refreshAndBindWidgetsForPackageUser(null); - } - } - /** * @param packageUser if null, refreshes all widgets and shortcuts, otherwise only * refreshes the widgets and shortcuts associated with the given package/user diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java index cfb9b570b..02f05c30e 100644 --- a/src/com/android/launcher3/LauncherAnimUtils.java +++ b/src/com/android/launcher3/LauncherAnimUtils.java @@ -30,6 +30,16 @@ import java.util.HashSet; import java.util.WeakHashMap; public class LauncherAnimUtils { + /** + * Durations for various state animations. These are not defined in resources to allow + * easier access from static classes and enums + */ + public static final int ALL_APPS_TRANSITION_MS = 320; + public static final int OVERVIEW_TRANSITION_MS = 250; + public static final int SPRING_LOADED_TRANSITION_MS = 150; + public static final int SPRING_LOADED_EXIT_SHORT_TIMEOUT = 500; + public static final int SPRING_LOADED_EXIT_NEXT_FRAME = 0; + static WeakHashMap<Animator, Object> sAnimators = new WeakHashMap<Animator, Object>(); static Animator.AnimatorListener sEndAnimListener = new Animator.AnimatorListener() { public void onAnimationStart(Animator animation) { @@ -141,4 +151,18 @@ public class LauncherAnimUtils { drawable.setAlpha(alpha); } }; + + public static final Property<View, Float> SCALE_PROPERTY = + new Property<View, Float>(Float.class, "scale") { + @Override + public Float get(View view) { + return view.getScaleX(); + } + + @Override + public void set(View view, Float scale) { + view.setScaleX(scale); + view.setScaleY(scale); + } + }; } diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index 618bd0f73..469c5f1c0 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -134,7 +134,7 @@ public class LauncherModel extends BroadcastReceiver } }; - public interface Callbacks extends LauncherAppWidgetHost.ProviderChangedListener { + public interface Callbacks { public boolean setLoadOnResume(); public int getCurrentWorkspaceScreen(); public void clearPendingBinds(); diff --git a/src/com/android/launcher3/LauncherStateTransitionAnimation.java b/src/com/android/launcher3/LauncherStateTransitionAnimation.java index 5823734e4..9c83e3c01 100644 --- a/src/com/android/launcher3/LauncherStateTransitionAnimation.java +++ b/src/com/android/launcher3/LauncherStateTransitionAnimation.java @@ -19,7 +19,6 @@ package com.android.launcher3; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; -import android.content.res.Resources; import android.util.Log; import android.view.View; @@ -74,6 +73,7 @@ public class LauncherStateTransitionAnimation { public static final String TAG = "LSTAnimation"; + private final AnimationConfig mConfig = new AnimationConfig(); @Thunk Launcher mLauncher; @Thunk AnimatorSet mCurrentAnimation; AllAppsTransitionController mAllAppsController; @@ -86,24 +86,22 @@ public class LauncherStateTransitionAnimation { /** * Starts an animation to the apps view. */ - public void startAnimationToAllApps(final boolean animated) { + public void startAnimationToAllApps(boolean animated) { final AllAppsContainerView toView = mLauncher.getAppsView(); + // If for some reason our views aren't initialized, don't animate + animated = animated && (toView != null); + final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); - final Resources res = mLauncher.getResources(); - final int revealDurationSlide = res.getInteger(R.integer.config_overlaySlideRevealTime); final AnimationLayerSet layerViews = new AnimationLayerSet(); - // If for some reason our views aren't initialized, don't animate - boolean initialized = toView != null; - // Cancel the current animation cancelAnimation(); - playCommonTransitionAnimations(Workspace.State.NORMAL_HIDDEN, - animated, initialized, animation, layerViews); - if (!animated || !initialized) { + if (!animated) { + mLauncher.getWorkspace().setState(Workspace.State.NORMAL_HIDDEN); + mAllAppsController.finishPullUp(); toView.setTranslationX(0.0f); toView.setTranslationY(0.0f); @@ -115,6 +113,7 @@ public class LauncherStateTransitionAnimation { mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); return; } + if (!FeatureFlags.LAUNCHER3_PHYSICS) { // We are animating the content view alpha, so ensure we have a layer for it. layerViews.addView(toView); @@ -127,12 +126,16 @@ public class LauncherStateTransitionAnimation { mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); } }); - boolean shouldPost = mAllAppsController.animateToAllApps(animation, revealDurationSlide); + + mConfig.reset(); + mAllAppsController.animateToAllApps(animation, mConfig); + mLauncher.getWorkspace().setStateWithAnimation(Workspace.State.NORMAL_HIDDEN, + layerViews, animation, mConfig); Runnable startAnimRunnable = new StartAnimRunnable(animation, toView); mCurrentAnimation = animation; mCurrentAnimation.addListener(layerViews); - if (shouldPost) { + if (mConfig.shouldPost) { toView.post(startAnimRunnable); } else { startAnimRunnable.run(); @@ -140,14 +143,6 @@ public class LauncherStateTransitionAnimation { } /** - * Starts an animation to the widgets view. - */ - public void startAnimationToWidgets(final boolean animated) { - // TODO: Remove this - throw new RuntimeException("This cannot happen"); - } - - /** * Starts an animation to the workspace from the current overlay view. */ public void startAnimationToWorkspace(final Launcher.State fromState, @@ -159,8 +154,7 @@ public class LauncherStateTransitionAnimation { Log.e(TAG, "Unexpected call to startAnimationToWorkspace"); } - if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED - || mAllAppsController.isTransitioning()) { + if (fromState == Launcher.State.APPS || mAllAppsController.isTransitioning()) { startAnimationToWorkspaceFromAllApps(fromWorkspaceState, toWorkspaceState, animated, onCompleteRunnable); } else { @@ -170,54 +164,27 @@ public class LauncherStateTransitionAnimation { } /** - * Plays animations used by various transitions. - */ - private void playCommonTransitionAnimations( - Workspace.State toWorkspaceState, - boolean animated, boolean initialized, AnimatorSet animation, - AnimationLayerSet layerViews) { - // Create the workspace animation. - // NOTE: this call apparently also sets the state for the workspace if !animated - Animator workspaceAnim = mLauncher.getWorkspace(). - setStateWithAnimation(toWorkspaceState, animated, layerViews); - - if (animated && initialized) { - // Play the workspace animation - if (workspaceAnim != null) { - animation.play(workspaceAnim); - } - } - } - - /** * Starts an animation to the workspace from the apps view. */ private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState, - final Workspace.State toWorkspaceState, final boolean animated, + final Workspace.State toWorkspaceState, boolean animated, final Runnable onCompleteRunnable) { - final AllAppsContainerView fromView = mLauncher.getAppsView(); - final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); - final Resources res = mLauncher.getResources(); - final int revealDurationSlide = res.getInteger(R.integer.config_overlaySlideRevealTime); - - final View toView = mLauncher.getWorkspace(); + // If for some reason our views aren't initialized, don't animate + animated = animated & (fromView != null); + final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); final AnimationLayerSet layerViews = new AnimationLayerSet(); - // If for some reason our views aren't initialized, don't animate - boolean initialized = fromView != null; - // Cancel the current animation cancelAnimation(); - playCommonTransitionAnimations(toWorkspaceState, - animated, initialized, animation, layerViews); - if (!animated || !initialized) { + if (!animated) { if (fromWorkspaceState == Workspace.State.NORMAL_HIDDEN) { mAllAppsController.finishPullDown(); } fromView.setVisibility(View.GONE); + mLauncher.getWorkspace().setState(toWorkspaceState); mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); // Run any queued runnables @@ -227,9 +194,6 @@ public class LauncherStateTransitionAnimation { return; } - // We are animating the content view alpha, so ensure we have a layer for it - layerViews.addView(toView); - animation.addListener(new AnimatorListenerAdapter() { boolean canceled = false; @Override @@ -250,12 +214,16 @@ public class LauncherStateTransitionAnimation { } }); - boolean shouldPost = mAllAppsController.animateToWorkspace(animation, revealDurationSlide); - Runnable startAnimRunnable = new StartAnimRunnable(animation, toView); + mConfig.reset(); + mAllAppsController.animateToWorkspace(animation, mConfig); + mLauncher.getWorkspace().setStateWithAnimation(toWorkspaceState, layerViews, animation, + mConfig); + + Runnable startAnimRunnable = new StartAnimRunnable(animation, mLauncher.getWorkspace()); mCurrentAnimation = animation; mCurrentAnimation.addListener(layerViews); - if (shouldPost) { + if (mConfig.shouldPost) { fromView.post(startAnimRunnable); } else { startAnimRunnable.run(); @@ -269,39 +237,41 @@ public class LauncherStateTransitionAnimation { final Workspace.State toWorkspaceState, final boolean animated, final Runnable onCompleteRunnable) { final View fromWorkspace = mLauncher.getWorkspace(); - final AnimationLayerSet layerViews = new AnimationLayerSet(); - final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); - // Cancel the current animation cancelAnimation(); - playCommonTransitionAnimations(toWorkspaceState, animated, animated, animation, layerViews); mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); - if (animated) { - animation.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - // Run any queued runnables - if (onCompleteRunnable != null) { - onCompleteRunnable.run(); - } - - // This can hold unnecessary references to views. - cleanupAnimation(); - } - }); - animation.addListener(layerViews); - fromWorkspace.post(new StartAnimRunnable(animation, null)); - mCurrentAnimation = animation; - } else /* if (!animated) */ { + if (!animated) { + mLauncher.getWorkspace().setState(toWorkspaceState); // Run any queued runnables if (onCompleteRunnable != null) { onCompleteRunnable.run(); } - - mCurrentAnimation = null; + return; } + + final AnimationLayerSet layerViews = new AnimationLayerSet(); + final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet(); + mConfig.reset(); + mLauncher.getWorkspace().setStateWithAnimation(toWorkspaceState, + layerViews, animation, mConfig); + + animation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + // Run any queued runnables + if (onCompleteRunnable != null) { + onCompleteRunnable.run(); + } + + // This can hold unnecessary references to views. + cleanupAnimation(); + } + }); + animation.addListener(layerViews); + fromWorkspace.post(new StartAnimRunnable(animation, null)); + mCurrentAnimation = animation; } /** @@ -340,4 +310,23 @@ public class LauncherStateTransitionAnimation { mAnim.start(); } } + + public static class AnimationConfig { + public boolean shouldPost; + + private long mOverriddenDuration = -1; + + public void reset() { + shouldPost = false; + mOverriddenDuration = -1; + } + + public void overrideDuration(long duration) { + mOverriddenDuration = duration; + } + + public long getDuration(long defaultDuration) { + return mOverriddenDuration >= 0 ? mOverriddenDuration : defaultDuration; + } + } } diff --git a/src/com/android/launcher3/PinchAnimationManager.java b/src/com/android/launcher3/PinchAnimationManager.java index c3d3bb3df..10f35bde3 100644 --- a/src/com/android/launcher3/PinchAnimationManager.java +++ b/src/com/android/launcher3/PinchAnimationManager.java @@ -75,8 +75,7 @@ public class PinchAnimationManager { mOverviewScale = mWorkspace.getOverviewModeShrinkFactor(); mOverviewTranslationY = mWorkspace.getOverviewModeTranslationY(); - mNormalOverviewTransitionDuration = mWorkspace.getStateTransitionAnimation() - .mOverviewTransitionTime; + mNormalOverviewTransitionDuration = LauncherAnimUtils.OVERVIEW_TRANSITION_MS; } public int getNormalOverviewTransitionDuration() { @@ -131,7 +130,8 @@ public class PinchAnimationManager { mWorkspace.setScaleX(interpolatedScale); mWorkspace.setScaleY(interpolatedScale); mWorkspace.setTranslationY(interpolatedTranslationY); - setOverviewPanelsAlpha(1f - interpolatedProgress, 0); + int alpha = (int) ((1f - interpolatedProgress) * 255); + setOverviewPanelsAlpha(alpha, 0); } /** @@ -180,14 +180,15 @@ public class PinchAnimationManager { } } - private void setOverviewPanelsAlpha(float alpha, int duration) { + private void setOverviewPanelsAlpha(int alpha, int duration) { int childCount = mWorkspace.getChildCount(); for (int i = 0; i < childCount; i++) { final CellLayout cl = (CellLayout) mWorkspace.getChildAt(i); if (duration == 0) { - cl.setBackgroundAlpha(alpha); + cl.getScrimBackground().setAlpha(alpha); } else { - ObjectAnimator.ofFloat(cl, "backgroundAlpha", alpha).setDuration(duration).start(); + ObjectAnimator.ofInt(cl.getScrimBackground(), + LauncherAnimUtils.DRAWABLE_ALPHA, alpha).setDuration(duration).start(); } } } @@ -202,9 +203,9 @@ public class PinchAnimationManager { } private void animateScrim(boolean show) { - float endValue = show ? mWorkspace.getStateTransitionAnimation().mWorkspaceScrimAlpha : 0; - startAnimator(INDEX_SCRIM, - ObjectAnimator.ofFloat(mLauncher.getDragLayer(), "backgroundAlpha", endValue), + int endValue = show ? mWorkspace.getStateTransitionAnimation().mWorkspaceScrimAlpha : 0; + startAnimator(INDEX_SCRIM, ObjectAnimator.ofInt( + mLauncher.getDragLayer().getScrim(), LauncherAnimUtils.DRAWABLE_ALPHA, endValue), mNormalOverviewTransitionDuration); } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 1525e41d2..b57ce6375 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -16,6 +16,12 @@ package com.android.launcher3; +import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_NEXT_FRAME; +import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_SHORT_TIMEOUT; +import static com.android.launcher3.LauncherAnimUtils.ALL_APPS_TRANSITION_MS; +import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS; +import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_TRANSITION_MS; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; @@ -49,12 +55,14 @@ import android.view.View; import android.view.ViewDebug; import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; +import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; import android.widget.Toast; import com.android.launcher3.Launcher.LauncherOverlay; import com.android.launcher3.LauncherAppWidgetHost.ProviderChangedListener; +import com.android.launcher3.LauncherStateTransitionAnimation.AnimationConfig; import com.android.launcher3.accessibility.AccessibleDragListenerAdapter; import com.android.launcher3.accessibility.OverviewAccessibilityDelegate; import com.android.launcher3.accessibility.OverviewScreenAccessibilityDelegate; @@ -181,20 +189,26 @@ public class Workspace extends PagedView // in all apps or customize mode) public enum State { - NORMAL (false, false, ContainerType.WORKSPACE), - NORMAL_HIDDEN (false, false, ContainerType.ALLAPPS), - SPRING_LOADED (false, true, ContainerType.WORKSPACE), - OVERVIEW (true, true, ContainerType.OVERVIEW), - OVERVIEW_HIDDEN (true, false, ContainerType.WIDGETS); + NORMAL (false, ContainerType.WORKSPACE, false, 1, 0), + NORMAL_HIDDEN (false, ContainerType.ALLAPPS, false, 1, ALL_APPS_TRANSITION_MS), + SPRING_LOADED (true, ContainerType.WORKSPACE, true, 1, SPRING_LOADED_TRANSITION_MS), + OVERVIEW (true, ContainerType.OVERVIEW, true, 0, OVERVIEW_TRANSITION_MS); - public final boolean shouldUpdateWidget; public final boolean hasMultipleVisiblePages; public final int containerType; - State(boolean shouldUpdateWidget, boolean hasMultipleVisiblePages, int containerType) { - this.shouldUpdateWidget = shouldUpdateWidget; + // Properties related to state transition animation. + public final boolean hasScrim; + public final float hotseatAlpha; + public final int transitionDuration; + + State(boolean hasMultipleVisiblePages, int containerType, + boolean hasScrim, float hotseatAlpha, int transitionDuration) { this.hasMultipleVisiblePages = hasMultipleVisiblePages; this.containerType = containerType; + this.hasScrim = hasScrim; + this.hotseatAlpha = hotseatAlpha; + this.transitionDuration = transitionDuration; } } @@ -1296,9 +1310,7 @@ public class Workspace extends PagedView } }); - AccessibilityManager am = (AccessibilityManager) - mLauncher.getSystemService(Context.ACCESSIBILITY_SERVICE); - final boolean accessibilityEnabled = am.isEnabled(); + final boolean accessibilityEnabled = isAccessibilityEnabled(); animator.addUpdateListener( new AlphaUpdateListener(mLauncher.getHotseat(), accessibilityEnabled)); animator.addUpdateListener( @@ -1307,6 +1319,12 @@ public class Workspace extends PagedView } } + protected boolean isAccessibilityEnabled() { + AccessibilityManager am = (AccessibilityManager) + mLauncher.getSystemService(Context.ACCESSIBILITY_SERVICE); + return am.isEnabled(); + } + @Override protected void notifyPageSwitchListener(int prevPage) { super.notifyPageSwitchListener(prevPage); @@ -1562,7 +1580,7 @@ public class Workspace extends PagedView } public void snapToPageFromOverView(int whichPage) { - mStateTransitionAnimation.snapToPageFromOverView(whichPage); + snapToPage(whichPage, OVERVIEW_TRANSITION_MS, new ZoomInInterpolator()); } int getOverviewModeTranslationY() { @@ -1606,45 +1624,42 @@ public class Workspace extends PagedView return mOverviewModeShrinkFactor; } + /** - * Sets the current workspace {@link State}, returning an animation transitioning the workspace - * to that new state. + * Sets the current workspace {@link State} and updates the UI without any animations */ - public Animator setStateWithAnimation(State toState, boolean animated, - AnimationLayerSet layerViews) { - final State fromState = mState; - + public void setState(State toState) { // Update the current state mState = toState; - - // Create the animation to the new state - AnimatorSet workspaceAnim = mStateTransitionAnimation.getAnimationToState(fromState, - toState, animated, layerViews); - - boolean shouldNotifyWidgetChange = !fromState.shouldUpdateWidget - && toState.shouldUpdateWidget; + mStateTransitionAnimation.setState(mState); updateAccessibilityFlags(); + onPrepareStateTransition(mState.hasMultipleVisiblePages); + onStartStateTransition(); + onEndStateTransition(); + } - if (shouldNotifyWidgetChange) { - mLauncher.notifyWidgetProvidersChanged(); - } + /** + * Sets the current workspace {@link State}, while animating the UI + */ + public void setStateWithAnimation(State toState, AnimationLayerSet layerViews, AnimatorSet anim, + AnimationConfig config) { + final State fromState = mState; + // Update the current state + mState = toState; + mStateTransitionAnimation.setStateWithAnimation( + fromState, toState, anim, layerViews, config); + + updateAccessibilityFlags(); onPrepareStateTransition(mState.hasMultipleVisiblePages); StateTransitionListener listener = new StateTransitionListener(); - if (animated) { - ValueAnimator stepAnimator = ValueAnimator.ofFloat(0, 1); - stepAnimator.addUpdateListener(listener); - - workspaceAnim.play(stepAnimator); - workspaceAnim.addListener(listener); - } else { - listener.onAnimationStart(null); - listener.onAnimationEnd(null); - } + ValueAnimator stepAnimator = ValueAnimator.ofFloat(0, 1); + stepAnimator.addUpdateListener(listener); - return workspaceAnim; + anim.play(stepAnimator); + anim.addListener(listener); } public State getState() { @@ -1701,11 +1716,31 @@ public class Workspace extends PagedView updateChildrenLayersEnabled(); } + private void onStartStateTransition() { + if (mState == State.SPRING_LOADED) { + // Show the page indicator at the same time as the rest of the transition. + showPageIndicatorAtCurrentScroll(); + } + getPageIndicator().setShouldAutoHide(mState != State.SPRING_LOADED); + } + public void onEndStateTransition() { mIsSwitchingState = false; updateChildrenLayersEnabled(); mForceDrawAdjacentPages = false; mTransitionProgress = 1; + + if (mState == State.OVERVIEW) { + enableFreeScroll(); + } else { + disableFreeScroll(); + } + + ViewGroup overviewPanel = mLauncher.getOverviewPanel(); + if (isAccessibilityEnabled() && overviewPanel.getVisibility() == View.VISIBLE) { + overviewPanel.getChildAt(0).performAccessibilityAction( + AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null); + } } public void startDrag(CellLayout.CellInfo cellInfo, DragOptions options) { @@ -2076,8 +2111,7 @@ public class Workspace extends PagedView dropTargetLayout, mTargetCell, distance, false, d.dragView) || addToExistingFolderIfNecessary(cell, dropTargetLayout, mTargetCell, distance, d, false)) { - mLauncher.exitSpringLoadedDragMode(true, - Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT); + mLauncher.exitSpringLoadedDragMode(SPRING_LOADED_EXIT_SHORT_TIMEOUT); return; } @@ -2191,9 +2225,8 @@ public class Workspace extends PagedView // Animate the item to its original position, while simultaneously exiting // spring-loaded mode so the page meets the icon where it was picked up. mLauncher.getDragController().animateDragViewToOriginalPosition( - onCompleteRunnable, cell, - mStateTransitionAnimation.mSpringLoadedTransitionTime); - mLauncher.exitSpringLoadedDragMode(false, 0); + onCompleteRunnable, cell, SPRING_LOADED_TRANSITION_MS); + mLauncher.exitSpringLoadedDragMode(SPRING_LOADED_EXIT_NEXT_FRAME); mLauncher.getDropTargetBar().onDragEnd(); parent.onDropChild(cell); return; @@ -2216,8 +2249,8 @@ public class Workspace extends PagedView } parent.onDropChild(cell); - mLauncher.exitSpringLoadedDragMode(true, - Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, onCompleteRunnable); + mLauncher.exitSpringLoadedDragMode( + SPRING_LOADED_EXIT_SHORT_TIMEOUT, onCompleteRunnable); } if (d.stateAnnouncer != null && !droppedOnOriginalCell) { @@ -2824,8 +2857,7 @@ public class Workspace extends PagedView animationStyle, finalView, true); } else { // This is for other drag/drop cases, like dragging from All Apps - mLauncher.exitSpringLoadedDragMode(true, - Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT); + mLauncher.exitSpringLoadedDragMode(SPRING_LOADED_EXIT_SHORT_TIMEOUT); View view; @@ -2887,10 +2919,9 @@ public class Workspace extends PagedView // We wrap the animation call in the temporary set and reset of the current // cellLayout to its final transform -- this means we animate the drag view to // the correct final location. - setFinalTransitionTransform(cellLayout); - mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, view, - this); - resetTransitionTransform(cellLayout); + setFinalTransitionTransform(); + mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, view, this); + resetTransitionTransform(); } } } @@ -2926,10 +2957,10 @@ public class Workspace extends PagedView loc[0] = r.left; loc[1] = r.top; - setFinalTransitionTransform(layout); + setFinalTransitionTransform(); float cellLayoutScale = mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(layout, loc, true); - resetTransitionTransform(layout); + resetTransitionTransform(); if (scale) { float dragViewScaleX = (1.0f * r.width()) / dragView.getMeasuredWidth(); @@ -3013,14 +3044,14 @@ public class Workspace extends PagedView } } - public void setFinalTransitionTransform(CellLayout layout) { + public void setFinalTransitionTransform() { if (isSwitchingState()) { mCurrentScale = getScaleX(); setScaleX(mStateTransitionAnimation.getFinalScale()); setScaleY(mStateTransitionAnimation.getFinalScale()); } } - public void resetTransitionTransform(CellLayout layout) { + public void resetTransitionTransform() { if (isSwitchingState()) { setScaleX(mCurrentScale); setScaleY(mCurrentScale); @@ -3641,11 +3672,8 @@ public class Workspace extends PagedView @Override public void onAnimationStart(Animator animation) { - if (mState == State.SPRING_LOADED) { - // Show the page indicator at the same time as the rest of the transition. - showPageIndicatorAtCurrentScroll(); - } mTransitionProgress = 0; + onStartStateTransition(); } @Override diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java index e84d3b4e6..9d9e9fb1a 100644 --- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java +++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java @@ -16,6 +16,9 @@ package com.android.launcher3; +import static com.android.launcher3.LauncherAnimUtils.DRAWABLE_ALPHA; +import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; @@ -24,17 +27,14 @@ import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.Resources; +import android.util.Property; import android.view.View; -import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; -import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.DecelerateInterpolator; +import com.android.launcher3.LauncherStateTransitionAnimation.AnimationConfig; +import com.android.launcher3.Workspace.State; import com.android.launcher3.anim.AnimationLayerSet; -import com.android.launcher3.anim.PropertyListBuilder; -import com.android.launcher3.config.FeatureFlags; -import com.android.launcher3.dragndrop.DragLayer; -import com.android.launcher3.util.Thunk; /** * A convenience class to update a view's visibility state after an alpha animation. @@ -131,78 +131,24 @@ class ZoomInInterpolator implements TimeInterpolator { } /** - * Stores the transition states for convenience. - */ -class TransitionStates { - - // Raw states - final boolean oldStateIsNormal; - final boolean oldStateIsSpringLoaded; - final boolean oldStateIsNormalHidden; - final boolean oldStateIsOverviewHidden; - final boolean oldStateIsOverview; - - final boolean stateIsNormal; - final boolean stateIsSpringLoaded; - final boolean stateIsNormalHidden; - final boolean stateIsOverviewHidden; - final boolean stateIsOverview; - - // Convenience members - final boolean workspaceToAllApps; - final boolean overviewToAllApps; - final boolean allAppsToWorkspace; - final boolean workspaceToOverview; - final boolean overviewToWorkspace; - - public TransitionStates(final Workspace.State fromState, final Workspace.State toState) { - oldStateIsNormal = (fromState == Workspace.State.NORMAL); - oldStateIsSpringLoaded = (fromState == Workspace.State.SPRING_LOADED); - oldStateIsNormalHidden = (fromState == Workspace.State.NORMAL_HIDDEN); - oldStateIsOverviewHidden = (fromState == Workspace.State.OVERVIEW_HIDDEN); - oldStateIsOverview = (fromState == Workspace.State.OVERVIEW); - - stateIsNormal = (toState == Workspace.State.NORMAL); - stateIsSpringLoaded = (toState == Workspace.State.SPRING_LOADED); - stateIsNormalHidden = (toState == Workspace.State.NORMAL_HIDDEN); - stateIsOverviewHidden = (toState == Workspace.State.OVERVIEW_HIDDEN); - stateIsOverview = (toState == Workspace.State.OVERVIEW); - - workspaceToOverview = (oldStateIsNormal && stateIsOverview); - workspaceToAllApps = (oldStateIsNormal && stateIsNormalHidden); - overviewToWorkspace = (oldStateIsOverview && stateIsNormal); - overviewToAllApps = (oldStateIsOverview && stateIsOverviewHidden); - allAppsToWorkspace = (oldStateIsNormalHidden && stateIsNormal); - } -} - -/** * Manages the animations between each of the workspace states. */ public class WorkspaceStateTransitionAnimation { - public static final String TAG = "WorkspaceStateTransitionAnimation"; - - @Thunk static final int BACKGROUND_FADE_OUT_DURATION = 350; + private static final PropertySetter NO_ANIM_PROPERTY_SETTER = new PropertySetter(); - final @Thunk Launcher mLauncher; - final @Thunk Workspace mWorkspace; + private final ZoomInInterpolator mZoomInInterpolator = new ZoomInInterpolator(); - @Thunk AnimatorSet mStateAnimator; + public final int mWorkspaceScrimAlpha; - @Thunk float mCurrentScale; - @Thunk float mNewScale; + private final Launcher mLauncher; + private final Workspace mWorkspace; - @Thunk final ZoomInInterpolator mZoomInInterpolator = new ZoomInInterpolator(); + private final float mSpringLoadedShrinkFactor; + private final float mOverviewModeShrinkFactor; + private final boolean mWorkspaceFadeInAdjacentScreens; - @Thunk float mSpringLoadedShrinkFactor; - @Thunk float mOverviewModeShrinkFactor; - @Thunk float mWorkspaceScrimAlpha; - @Thunk int mAllAppsTransitionTime; - @Thunk int mOverviewTransitionTime; - @Thunk int mOverlayTransitionTime; - @Thunk int mSpringLoadedTransitionTime; - @Thunk boolean mWorkspaceFadeInAdjacentScreens; + private float mNewScale; public WorkspaceStateTransitionAnimation(Launcher launcher, Workspace workspace) { mLauncher = launcher; @@ -210,32 +156,24 @@ public class WorkspaceStateTransitionAnimation { DeviceProfile grid = mLauncher.getDeviceProfile(); Resources res = launcher.getResources(); - mAllAppsTransitionTime = res.getInteger(R.integer.config_allAppsTransitionTime); - mOverviewTransitionTime = res.getInteger(R.integer.config_overviewTransitionTime); - mOverlayTransitionTime = res.getInteger(R.integer.config_overlayTransitionTime); - mSpringLoadedTransitionTime = mOverlayTransitionTime / 2; mSpringLoadedShrinkFactor = mLauncher.getDeviceProfile().workspaceSpringLoadShrinkFactor; mOverviewModeShrinkFactor = res.getInteger(R.integer.config_workspaceOverviewShrinkPercentage) / 100f; - mWorkspaceScrimAlpha = res.getInteger(R.integer.config_workspaceScrimAlpha) / 100f; + mWorkspaceScrimAlpha = res.getInteger(R.integer.config_workspaceScrimAlpha); mWorkspaceFadeInAdjacentScreens = grid.shouldFadeAdjacentWorkspaceScreens(); } - public void snapToPageFromOverView(int whichPage) { - mWorkspace.snapToPage(whichPage, mOverviewTransitionTime, mZoomInInterpolator); + public void setState(Workspace.State toState) { + setWorkspaceProperty(toState, NO_ANIM_PROPERTY_SETTER); } - public AnimatorSet getAnimationToState(Workspace.State fromState, Workspace.State toState, - boolean animated, AnimationLayerSet layerViews) { - AccessibilityManager am = (AccessibilityManager) - mLauncher.getSystemService(Context.ACCESSIBILITY_SERVICE); - final boolean accessibilityEnabled = am.isEnabled(); - TransitionStates states = new TransitionStates(fromState, toState); - int workspaceDuration = getAnimationDuration(states); - animateWorkspace(states, animated, workspaceDuration, layerViews, - accessibilityEnabled); - animateBackgroundGradient(states, animated, BACKGROUND_FADE_OUT_DURATION); - return mStateAnimator; + public void setStateWithAnimation(Workspace.State fromState, Workspace.State toState, + AnimatorSet anim, AnimationLayerSet layerViews, AnimationConfig config) { + long duration = config.getDuration(toState == State.NORMAL + ? fromState.transitionDuration : toState.transitionDuration); + AnimatedPropertySetter proertSetter = + new AnimatedPropertySetter(duration, layerViews, anim); + setWorkspaceProperty(toState, proertSetter); } public float getFinalScale() { @@ -243,242 +181,138 @@ public class WorkspaceStateTransitionAnimation { } /** - * Returns the proper animation duration for a transition. - */ - private int getAnimationDuration(TransitionStates states) { - if (states.workspaceToAllApps || states.overviewToAllApps) { - return mAllAppsTransitionTime; - } else if (states.workspaceToOverview || states.overviewToWorkspace) { - return mOverviewTransitionTime; - } else if (mLauncher.mState == Launcher.State.WORKSPACE_SPRING_LOADED - || states.oldStateIsNormal && states.stateIsSpringLoaded) { - return mSpringLoadedTransitionTime; - } else { - return mOverlayTransitionTime; - } - } - - /** * Starts a transition animation for the workspace. */ - private void animateWorkspace(final TransitionStates states, final boolean animated, - final int duration, AnimationLayerSet layerViews, final boolean accessibilityEnabled) { - // Cancel existing workspace animations and create a new animator set if requested - cancelAnimation(); - if (animated) { - mStateAnimator = LauncherAnimUtils.createAnimatorSet(); - } - + private void setWorkspaceProperty(Workspace.State state, PropertySetter propertySetter) { // Update the workspace state - float finalBackgroundAlpha = (states.stateIsSpringLoaded || states.stateIsOverview) ? - 1.0f : 0f; - float finalHotseatAlpha = (states.stateIsNormal || states.stateIsSpringLoaded || - states.stateIsNormalHidden) ? 1f : 0f; - - float finalWorkspaceTranslationY = 0; - if (states.stateIsOverview || states.stateIsOverviewHidden) { - finalWorkspaceTranslationY = mWorkspace.getOverviewModeTranslationY(); - } else if (states.stateIsSpringLoaded) { - finalWorkspaceTranslationY = mWorkspace.getSpringLoadedTranslationY(); - } - - final int childCount = mWorkspace.getChildCount(); - - mNewScale = 1.0f; + int finalBackgroundAlpha = state.hasScrim ? 255 : 0; - if (states.oldStateIsOverview) { - mWorkspace.disableFreeScroll(); - } else if (states.stateIsOverview) { - mWorkspace.enableFreeScroll(); - } - - if (!states.stateIsNormal) { - if (states.stateIsSpringLoaded) { - mNewScale = mSpringLoadedShrinkFactor; - } else if (states.stateIsOverview || states.stateIsOverviewHidden) { + final float finalWorkspaceTranslationY; + switch (state) { + case OVERVIEW: mNewScale = mOverviewModeShrinkFactor; - } + finalWorkspaceTranslationY = mWorkspace.getOverviewModeTranslationY(); + break; + case SPRING_LOADED: + mNewScale = mSpringLoadedShrinkFactor; + finalWorkspaceTranslationY = mWorkspace.getSpringLoadedTranslationY(); + break; + default: + mNewScale = 1f; + finalWorkspaceTranslationY = 0; } int toPage = mWorkspace.getPageNearestToCenterOfScreen(); - // TODO: Animate the celllayout alpha instead of the pages. + final int childCount = mWorkspace.getChildCount(); for (int i = 0; i < childCount; i++) { final CellLayout cl = (CellLayout) mWorkspace.getChildAt(i); - float initialAlpha = cl.getShortcutsAndWidgets().getAlpha(); - float finalAlpha; - if (states.stateIsOverviewHidden) { - finalAlpha = 0f; - } else if(states.stateIsNormalHidden) { - finalAlpha = (i == mWorkspace.getNextPage()) ? 1 : 0; - } else if (states.stateIsNormal && mWorkspaceFadeInAdjacentScreens) { - finalAlpha = (i == toPage) ? 1f : 0f; - } else { - finalAlpha = 1f; + propertySetter.setInt(cl.getScrimBackground(), + DRAWABLE_ALPHA, finalBackgroundAlpha, mZoomInInterpolator); + + // Only animate the page alpha when we actually fade pages + if (mWorkspaceFadeInAdjacentScreens) { + float finalAlpha = state == State.NORMAL && i != toPage ? 0 : 1f; + propertySetter.setFloat(cl.getShortcutsAndWidgets(), View.ALPHA, + finalAlpha, mZoomInInterpolator); } + } - // If we are animating to/from the small state, then hide the side pages and fade the - // current page in - if (!FeatureFlags.NO_ALL_APPS_ICON && !mWorkspace.isSwitchingState()) { - if (states.workspaceToAllApps || states.allAppsToWorkspace) { - boolean isCurrentPage = (i == toPage); - if (states.allAppsToWorkspace && isCurrentPage) { - initialAlpha = 0f; - } else if (!isCurrentPage) { - initialAlpha = finalAlpha = 0f; - } - cl.setShortcutAndWidgetAlpha(initialAlpha); - } - } + float finalHotseatAlpha = state.hotseatAlpha; - if (animated) { - float oldBackgroundAlpha = cl.getBackgroundAlpha(); - if (initialAlpha != finalAlpha) { - Animator alphaAnim = ObjectAnimator.ofFloat( - cl.getShortcutsAndWidgets(), View.ALPHA, finalAlpha); - alphaAnim.setDuration(duration) - .setInterpolator(mZoomInInterpolator); - mStateAnimator.play(alphaAnim); - } - if (oldBackgroundAlpha != 0 || finalBackgroundAlpha != 0) { - ValueAnimator bgAnim = ObjectAnimator.ofFloat(cl, "backgroundAlpha", - oldBackgroundAlpha, finalBackgroundAlpha); - bgAnim.setInterpolator(mZoomInInterpolator); - bgAnim.setDuration(duration); - mStateAnimator.play(bgAnim); - } - } else { - cl.setBackgroundAlpha(finalBackgroundAlpha); - cl.setShortcutAndWidgetAlpha(finalAlpha); + // This is true when transitioning between: + // - Overview <-> Workspace + propertySetter.setViewAlpha(null, mLauncher.getOverviewPanel(), 1 - finalHotseatAlpha); + propertySetter.setViewAlpha(mWorkspace.createHotseatAlphaAnimator(finalHotseatAlpha), + mLauncher.getHotseat(), finalHotseatAlpha); + + propertySetter.setFloat(mWorkspace, SCALE_PROPERTY, mNewScale, mZoomInInterpolator); + propertySetter.setFloat(mWorkspace, View.TRANSLATION_Y, + finalWorkspaceTranslationY, mZoomInInterpolator); + + // Set scrim + propertySetter.setInt(mLauncher.getDragLayer().getScrim(), DRAWABLE_ALPHA, + state.hasScrim ? mWorkspaceScrimAlpha : 0, new DecelerateInterpolator(1.5f)); + } + + private static class PropertySetter { + + public void setViewAlpha(Animator anim, View view, float alpha) { + if (anim != null) { + anim.end(); + return; } + view.setAlpha(alpha); + AlphaUpdateListener.updateVisibility(view, isAccessibilityEnabled(view)); } - final ViewGroup overviewPanel = mLauncher.getOverviewPanel(); - - float finalOverviewPanelAlpha = states.stateIsOverview ? 1f : 0f; - if (animated) { - // This is true when transitioning between: - // - Overview <-> Workspace - // - Overview <-> Widget Tray - if (finalOverviewPanelAlpha != overviewPanel.getAlpha()) { - Animator overviewPanelAlpha = ObjectAnimator.ofFloat( - overviewPanel, View.ALPHA, finalOverviewPanelAlpha); - overviewPanelAlpha.addListener(new AlphaUpdateListener(overviewPanel, - accessibilityEnabled)); - layerViews.addView(overviewPanel); - - if (states.overviewToWorkspace) { - overviewPanelAlpha.setInterpolator(new DecelerateInterpolator(2)); - } else if (states.workspaceToOverview) { - overviewPanelAlpha.setInterpolator(null); - } + public <T> void setFloat(T target, Property<T, Float> property, float value, + TimeInterpolator interpolator) { + property.set(target, value); + } - overviewPanelAlpha.setDuration(duration); - mStateAnimator.play(overviewPanelAlpha); - } + public <T> void setInt(T target, Property<T, Integer> property, int value, + TimeInterpolator interpolator) { + property.set(target, value); + } - Animator scale = LauncherAnimUtils.ofPropertyValuesHolder(mWorkspace, - new PropertyListBuilder().scale(mNewScale) - .translationY(finalWorkspaceTranslationY).build()) - .setDuration(duration); - scale.setInterpolator(mZoomInInterpolator); - mStateAnimator.play(scale); - - // For animation optimization, we may need to provide the Launcher transition - // with a set of views on which to force build and manage layers in certain scenarios. - layerViews.addView(mLauncher.getHotseat()); - layerViews.addView(mWorkspace.getPageIndicator()); - - Animator hotseatAlpha = mWorkspace.createHotseatAlphaAnimator(finalHotseatAlpha); - if (states.workspaceToOverview) { - hotseatAlpha.setInterpolator(new DecelerateInterpolator(2)); - } else if (states.overviewToWorkspace) { - hotseatAlpha.setInterpolator(null); - } - hotseatAlpha.setDuration(duration); - mStateAnimator.play(hotseatAlpha); - mStateAnimator.addListener(new AnimatorListenerAdapter() { - boolean canceled = false; - @Override - public void onAnimationCancel(Animator animation) { - canceled = true; - } + protected boolean isAccessibilityEnabled(View v) { + AccessibilityManager am = (AccessibilityManager) + v.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); + return am.isEnabled(); + } + } - @Override - public void onAnimationStart(Animator animation) { - mWorkspace.getPageIndicator().setShouldAutoHide(!states.stateIsSpringLoaded); - } + private static class AnimatedPropertySetter extends PropertySetter { + + private final long mDuration; + private final AnimationLayerSet mLayerViews; + private final AnimatorSet mStateAnimator; + + AnimatedPropertySetter(long duration, AnimationLayerSet layerView, AnimatorSet anim) { + mDuration = duration; + mLayerViews = layerView; + mStateAnimator = anim; + } - @Override - public void onAnimationEnd(Animator animation) { - mStateAnimator = null; - if (canceled) return; - if (accessibilityEnabled && overviewPanel.getVisibility() == View.VISIBLE) { - overviewPanel.getChildAt(0).performAccessibilityAction( - AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null); - } + @Override + public void setViewAlpha(Animator anim, View view, float alpha) { + if (anim == null) { + if (view.getAlpha() == alpha) { + return; } - }); - } else { - overviewPanel.setAlpha(finalOverviewPanelAlpha); - AlphaUpdateListener.updateVisibility(overviewPanel, accessibilityEnabled); - mWorkspace.getPageIndicator().setShouldAutoHide(!states.stateIsSpringLoaded); - - mWorkspace.createHotseatAlphaAnimator(finalHotseatAlpha).end(); - mWorkspace.setScaleX(mNewScale); - mWorkspace.setScaleY(mNewScale); - mWorkspace.setTranslationY(finalWorkspaceTranslationY); - - if (accessibilityEnabled && overviewPanel.getVisibility() == View.VISIBLE) { - overviewPanel.getChildAt(0).performAccessibilityAction( - AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null); + anim = ObjectAnimator.ofFloat(view, View.ALPHA, alpha); + anim.addListener(new AlphaUpdateListener(view, isAccessibilityEnabled(view))); } + + anim.setDuration(mDuration).setInterpolator(getFadeInterpolator(alpha)); + mLayerViews.addView(view); + mStateAnimator.play(anim); } - } - /** - * Animates the background scrim. Add to the state animator to prevent jankiness. - * - * @param states the current and final workspace states - * @param animated whether or not to set the background alpha immediately - * @duration duration of the animation - */ - private void animateBackgroundGradient(TransitionStates states, - boolean animated, int duration) { - - final DragLayer dragLayer = mLauncher.getDragLayer(); - final float startAlpha = dragLayer.getBackgroundAlpha(); - float finalAlpha = states.stateIsNormal || states.stateIsNormalHidden ? - 0 : mWorkspaceScrimAlpha; - - if (finalAlpha != startAlpha) { - if (animated) { - // These properties refer to the background protection gradient used for AllApps - // and Widget tray. - ValueAnimator bgFadeOutAnimation = ValueAnimator.ofFloat(startAlpha, finalAlpha); - bgFadeOutAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - dragLayer.setBackgroundAlpha( - ((Float)animation.getAnimatedValue()).floatValue()); - } - }); - bgFadeOutAnimation.setInterpolator(new DecelerateInterpolator(1.5f)); - bgFadeOutAnimation.setDuration(duration); - mStateAnimator.play(bgFadeOutAnimation); - } else { - dragLayer.setBackgroundAlpha(finalAlpha); + @Override + public <T> void setFloat(T target, Property<T, Float> property, float value, + TimeInterpolator interpolator) { + if (property.get(target) == value) { + return; } + Animator anim = ObjectAnimator.ofFloat(target, property, value); + anim.setDuration(mDuration).setInterpolator(interpolator); + mStateAnimator.play(anim); } - } - /** - * Cancels the current animation. - */ - private void cancelAnimation() { - if (mStateAnimator != null) { - mStateAnimator.setDuration(0); - mStateAnimator.cancel(); + @Override + public <T> void setInt(T target, Property<T, Integer> property, int value, + TimeInterpolator interpolator) { + if (property.get(target) == value) { + return; + } + Animator anim = ObjectAnimator.ofInt(target, property, value); + anim.setDuration(mDuration).setInterpolator(interpolator); + mStateAnimator.play(anim); + } + + private TimeInterpolator getFadeInterpolator(float finalAlpha) { + return finalAlpha == 0 ? new DecelerateInterpolator(2) : null; } - mStateAnimator = null; } }
\ No newline at end of file diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index bb0822f95..5642b4c01 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -11,12 +11,14 @@ import android.support.v4.view.animation.FastOutSlowInInterpolator; import android.view.MotionEvent; import android.view.View; import android.view.animation.AccelerateInterpolator; +import android.view.animation.Animation; import android.view.animation.Interpolator; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.Hotseat; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAnimUtils; +import com.android.launcher3.LauncherStateTransitionAnimation.AnimationConfig; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; @@ -329,15 +331,15 @@ public class AllAppsTransitionController implements TouchController, SwipeDetect mAnimationDuration = SwipeDetector.calculateDuration(velocity, disp / mShiftRange); } - public boolean animateToAllApps(AnimatorSet animationOut, long duration) { - boolean shouldPost = true; + public void animateToAllApps(AnimatorSet animationOut, AnimationConfig outConfig) { + outConfig.shouldPost = true; if (animationOut == null) { - return shouldPost; + return; } Interpolator interpolator; if (mDetector.isIdleState()) { preparePull(true); - mAnimationDuration = duration; + mAnimationDuration = LauncherAnimUtils.ALL_APPS_TRANSITION_MS; mShiftStart = mAppsView.getTranslationY(); interpolator = mFastOutSlowInInterpolator; } else { @@ -347,9 +349,10 @@ public class AllAppsTransitionController implements TouchController, SwipeDetect if (nextFrameProgress >= 0f) { mProgress = nextFrameProgress; } - shouldPost = false; + outConfig.shouldPost = false; } + outConfig.overrideDuration(mAnimationDuration); ObjectAnimator driftAndAlpha = ObjectAnimator.ofFloat(this, "progress", mProgress, 0f); driftAndAlpha.setDuration(mAnimationDuration); @@ -396,7 +399,6 @@ public class AllAppsTransitionController implements TouchController, SwipeDetect } }); mCurrentAnimation = animationOut; - return shouldPost; } public void showDiscoveryBounce() { @@ -432,15 +434,15 @@ public class AllAppsTransitionController implements TouchController, SwipeDetect }); } - public boolean animateToWorkspace(AnimatorSet animationOut, long duration) { - boolean shouldPost = true; + public void animateToWorkspace(AnimatorSet animationOut, AnimationConfig outconfig) { + outconfig.shouldPost = true; if (animationOut == null) { - return shouldPost; + return; } Interpolator interpolator; if (mDetector.isIdleState()) { preparePull(true); - mAnimationDuration = duration; + mAnimationDuration = LauncherAnimUtils.ALL_APPS_TRANSITION_MS; mShiftStart = mAppsView.getTranslationY(); interpolator = mFastOutSlowInInterpolator; } else { @@ -450,9 +452,10 @@ public class AllAppsTransitionController implements TouchController, SwipeDetect if (nextFrameProgress <= 1f) { mProgress = nextFrameProgress; } - shouldPost = false; + outconfig.shouldPost = false; } + outconfig.overrideDuration(mAnimationDuration); ObjectAnimator driftAndAlpha = ObjectAnimator.ofFloat(this, "progress", mProgress, 1f); driftAndAlpha.setDuration(mAnimationDuration); @@ -479,7 +482,6 @@ public class AllAppsTransitionController implements TouchController, SwipeDetect } }); mCurrentAnimation = animationOut; - return shouldPost; } public void finishPullUp() { diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java index 31255b7f0..8386f8ffa 100644 --- a/src/com/android/launcher3/dragndrop/DragController.java +++ b/src/com/android/launcher3/dragndrop/DragController.java @@ -16,6 +16,8 @@ package com.android.launcher3.dragndrop; +import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_SHORT_TIMEOUT; + import android.content.ComponentName; import android.content.res.Resources; import android.graphics.Bitmap; @@ -261,8 +263,7 @@ public class DragController implements DragDriver.EventListener, TouchController if (!accepted) { // If it was not accepted, cleanup the state. If it was accepted, it is the // responsibility of the drop target to cleanup the state. - mLauncher.exitSpringLoadedDragMode(false, - Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT); + mLauncher.exitSpringLoadedDragMode(SPRING_LOADED_EXIT_SHORT_TIMEOUT); mDragObject.deferDragViewCleanupPostAnimation = false; } diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java index 95223c3f7..bc5aafc0a 100644 --- a/src/com/android/launcher3/dragndrop/DragLayer.java +++ b/src/com/android/launcher3/dragndrop/DragLayer.java @@ -25,8 +25,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Rect; -import android.graphics.Region; -import android.support.v4.graphics.ColorUtils; +import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.MotionEvent; @@ -50,7 +49,6 @@ import com.android.launcher3.ShortcutAndWidgetContainer; import com.android.launcher3.Utilities; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.config.FeatureFlags; -import com.android.launcher3.dynamicui.WallpaperColorInfo; import com.android.launcher3.folder.Folder; import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.keyboard.ViewGroupFocusHelper; @@ -83,19 +81,15 @@ public class DragLayer extends InsettableFrameLayout { private boolean mHoverPointClosesFolder = false; private final Rect mHitRect = new Rect(); - private final Rect mHighlightRect = new Rect(); private TouchCompleteListener mTouchCompleteListener; private int mTopViewIndex; private int mChildCountOnLastUpdate = -1; - // Darkening scrim - private float mBackgroundAlpha = 0; - // Related to adjacent page hints private final ViewGroupFocusHelper mFocusIndicatorHelper; - private final WallpaperColorInfo mWallpaperColorInfo; + private final PageCutOutScrimDrawable mPageCutOutScrim; // Related to pinch-to-go-to-overview gesture. private PinchToOverviewListener mPinchListener = null; @@ -118,7 +112,8 @@ public class DragLayer extends InsettableFrameLayout { setChildrenDrawingOrderEnabled(true); mFocusIndicatorHelper = new ViewGroupFocusHelper(this); - mWallpaperColorInfo = WallpaperColorInfo.getInstance(getContext()); + mPageCutOutScrim = new PageCutOutScrimDrawable(this); + mPageCutOutScrim.setCallback(this); } public void setup(Launcher launcher, DragController dragController, @@ -141,6 +136,11 @@ public class DragLayer extends InsettableFrameLayout { return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event); } + @Override + protected boolean verifyDrawable(Drawable who) { + return super.verifyDrawable(who) || who == mPageCutOutScrim; + } + public void onAccessibilityStateChanged(boolean isAccessibilityEnabled) { mPinchListener = FeatureFlags.LAUNCHER3_DISABLE_PINCH_TO_OVERVIEW || isAccessibilityEnabled ? null : new PinchToOverviewListener(mLauncher); @@ -772,48 +772,23 @@ public class DragLayer extends InsettableFrameLayout { } public void invalidateScrim() { - if (mBackgroundAlpha > 0.0f) { + if (mPageCutOutScrim.getAlpha() > 0) { invalidate(); } } + public Drawable getScrim() { + return mPageCutOutScrim; + } + @Override protected void dispatchDraw(Canvas canvas) { // Draw the background below children. - if (mBackgroundAlpha > 0.0f) { - // Update the scroll position first to ensure scrim cutout is in the right place. - mLauncher.getWorkspace().computeScrollWithoutInvalidation(); - - int alpha = (int) (mBackgroundAlpha * 255); - CellLayout currCellLayout = mLauncher.getWorkspace().getCurrentDragOverlappingLayout(); - canvas.save(); - if (currCellLayout != null && currCellLayout != mLauncher.getHotseat().getLayout()) { - // Cut a hole in the darkening scrim on the page that should be highlighted, if any. - getDescendantRectRelativeToSelf(currCellLayout, mHighlightRect); - canvas.clipRect(mHighlightRect, Region.Op.DIFFERENCE); - } - // for super light wallpaper it needs to be darken for contrast to workspace - // for dark wallpapers the text is white so darkening works as well - int color = ColorUtils.compositeColors(0x66000000, mWallpaperColorInfo.getMainColor()); - canvas.drawColor(ColorUtils.setAlphaComponent(color, alpha)); - canvas.restore(); - } - + mPageCutOutScrim.draw(canvas); mFocusIndicatorHelper.draw(canvas); super.dispatchDraw(canvas); } - public void setBackgroundAlpha(float alpha) { - if (alpha != mBackgroundAlpha) { - mBackgroundAlpha = alpha; - invalidate(); - } - } - - public float getBackgroundAlpha() { - return mBackgroundAlpha; - } - @Override protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { View topView = AbstractFloatingView.getTopOpenView(mLauncher); diff --git a/src/com/android/launcher3/dragndrop/PageCutOutScrimDrawable.java b/src/com/android/launcher3/dragndrop/PageCutOutScrimDrawable.java new file mode 100644 index 000000000..367124b5d --- /dev/null +++ b/src/com/android/launcher3/dragndrop/PageCutOutScrimDrawable.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.dragndrop; + +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.Region; +import android.graphics.drawable.Drawable; +import android.support.v4.graphics.ColorUtils; + +import com.android.launcher3.CellLayout; +import com.android.launcher3.Launcher; +import com.android.launcher3.dynamicui.WallpaperColorInfo; + +/** + * Scrim drawable which draws a hole for the current drop target page. + */ +public class PageCutOutScrimDrawable extends Drawable { + + private final Rect mHighlightRect = new Rect(); + private final DragLayer mDragLayer; + private final Launcher mLauncher; + private final WallpaperColorInfo mWallpaperColorInfo; + + private int mAlpha = 0; + + public PageCutOutScrimDrawable(DragLayer dragLayer) { + mDragLayer = dragLayer; + mLauncher = Launcher.getLauncher(mDragLayer.getContext()); + mWallpaperColorInfo = WallpaperColorInfo.getInstance(mLauncher); + } + + @Override + public void draw(Canvas canvas) { + // Draw the background below children. + if (mAlpha > 0) { + // Update the scroll position first to ensure scrim cutout is in the right place. + mLauncher.getWorkspace().computeScrollWithoutInvalidation(); + CellLayout currCellLayout = mLauncher.getWorkspace().getCurrentDragOverlappingLayout(); + canvas.save(); + if (currCellLayout != null && currCellLayout != mLauncher.getHotseat().getLayout()) { + // Cut a hole in the darkening scrim on the page that should be highlighted, if any. + mDragLayer.getDescendantRectRelativeToSelf(currCellLayout, mHighlightRect); + canvas.clipRect(mHighlightRect, Region.Op.DIFFERENCE); + } + // for super light wallpaper it needs to be darken for contrast to workspace + // for dark wallpapers the text is white so darkening works as well + int color = ColorUtils.compositeColors(0x66000000, mWallpaperColorInfo.getMainColor()); + canvas.drawColor(ColorUtils.setAlphaComponent(color, mAlpha)); + canvas.restore(); + } + } + + @Override + public void setAlpha(int alpha) { + if (mAlpha != alpha) { + mAlpha = alpha; + invalidateSelf(); + } + } + + @Override + public int getAlpha() { + return mAlpha; + } + + @Override + public void setColorFilter(ColorFilter colorFilter) { } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } +} diff --git a/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java b/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java index a70a9bb1f..1da78349d 100644 --- a/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java +++ b/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java @@ -29,7 +29,7 @@ import android.os.Process; import com.android.launcher3.FastBitmapDrawable; import com.android.launcher3.IconCache; -import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; @@ -83,8 +83,8 @@ class PinShortcutRequestActivityInfo extends ShortcutConfigActivityInfo { public com.android.launcher3.ShortcutInfo createShortcutInfo() { // Total duration for the drop animation to complete. long duration = mContext.getResources().getInteger(R.integer.config_dropAnimMaxDuration) + - Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT + - mContext.getResources().getInteger(R.integer.config_overlayTransitionTime) / 2; + LauncherAnimUtils.SPRING_LOADED_EXIT_SHORT_TIMEOUT + + LauncherAnimUtils.SPRING_LOADED_TRANSITION_MS; // Delay the actual accept() call until the drop animation is complete. return LauncherAppsCompatVO.createShortcutInfoFromPinItemRequest( mContext, mRequest, duration); diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index 4a60d4c56..fae420eef 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -16,6 +16,8 @@ package com.android.launcher3.folder; +import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_SHORT_TIMEOUT; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; @@ -1241,8 +1243,7 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, true, mLauncher.getModelWriter()); } - mLauncher.exitSpringLoadedDragMode(true, - Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT); + mLauncher.exitSpringLoadedDragMode(SPRING_LOADED_EXIT_SHORT_TIMEOUT); if (d.stateAnnouncer != null) { d.stateAnnouncer.completeAction(R.string.item_moved); } diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java index cdb0ce367..ec448e997 100644 --- a/src/com/android/launcher3/folder/FolderAnimationManager.java +++ b/src/com/android/launcher3/folder/FolderAnimationManager.java @@ -16,6 +16,9 @@ package com.android.launcher3.folder; +import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; +import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; @@ -45,8 +48,6 @@ import com.android.launcher3.util.Themes; import java.util.List; -import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW; - /** * Manages the opening and closing animations for a {@link Folder}. * @@ -77,19 +78,6 @@ public class FolderAnimationManager { private final PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0, 0); - private static final Property<View, Float> SCALE_PROPERTY = - new Property<View, Float>(Float.class, "scale") { - @Override - public Float get(View view) { - return view.getScaleX(); - } - - @Override - public void set(View view, Float scale) { - view.setScaleX(scale); - view.setScaleY(scale); - } - }; public FolderAnimationManager(Folder folder, boolean isOpening) { mFolder = folder; diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java index d469eb254..900781cbb 100644 --- a/src/com/android/launcher3/folder/FolderIcon.java +++ b/src/com/android/launcher3/folder/FolderIcon.java @@ -296,7 +296,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { to = new Rect(); Workspace workspace = mLauncher.getWorkspace(); // Set cellLayout and this to it's final state to compute final animation locations - workspace.setFinalTransitionTransform((CellLayout) getParent().getParent()); + workspace.setFinalTransitionTransform(); float scaleX = getScaleX(); float scaleY = getScaleY(); setScaleX(1.0f); @@ -305,7 +305,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { // Finished computing final animation locations, restore current state setScaleX(scaleX); setScaleY(scaleY); - workspace.resetTransitionTransform((CellLayout) getParent().getParent()); + workspace.resetTransitionTransform(); } int numItemsInPreview = Math.min(MAX_NUM_ITEMS_IN_PREVIEW, index + 1); diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java index d5c6515c0..1a6dade31 100644 --- a/src/com/android/launcher3/logging/UserEventDispatcher.java +++ b/src/com/android/launcher3/logging/UserEventDispatcher.java @@ -177,13 +177,11 @@ public class UserEventDispatcher { } public void logActionCommand(int command, int containerType) { - logActionCommand(command, containerType, 0); + logActionCommand(command, newContainerTarget(containerType)); } - public void logActionCommand(int command, int containerType, int pageIndex) { - LauncherEvent event = newLauncherEvent( - newCommandAction(command), newContainerTarget(containerType)); - event.srcTarget[0].pageIndex = pageIndex; + public void logActionCommand(int command, Target target) { + LauncherEvent event = newLauncherEvent(newCommandAction(command), target); dispatchUserEvent(event, null); } diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java index 78ecbc621..53a986258 100644 --- a/src/com/android/launcher3/model/PackageUpdatedTask.java +++ b/src/com/android/launcher3/model/PackageUpdatedTask.java @@ -336,17 +336,7 @@ public class PackageUpdatedTask extends BaseModelUpdateTask { }); } - // Notify launcher of widget update. From marshmallow onwards we use AppWidgetHost to - // get widget update signals. - if (!Utilities.ATLEAST_MARSHMALLOW && - (mOp == OP_ADD || mOp == OP_REMOVE || mOp == OP_UPDATE)) { - scheduleCallbackTask(new CallbackTask() { - @Override - public void execute(Callbacks callbacks) { - callbacks.notifyWidgetProvidersChanged(); - } - }); - } else if (Utilities.ATLEAST_OREO && mOp == OP_ADD) { + if (Utilities.ATLEAST_OREO && mOp == OP_ADD) { // Load widgets for the new package. Changes due to app updates are handled through // AppWidgetHost events, this is just to initialize the long-press options. for (int i = 0; i < N; i++) { diff --git a/src/com/android/launcher3/util/FlingAnimation.java b/src/com/android/launcher3/util/FlingAnimation.java index 15f5af625..ec6276478 100644 --- a/src/com/android/launcher3/util/FlingAnimation.java +++ b/src/com/android/launcher3/util/FlingAnimation.java @@ -1,5 +1,7 @@ package com.android.launcher3.util; +import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_NEXT_FRAME; + import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; @@ -95,7 +97,7 @@ public class FlingAnimation implements AnimatorUpdateListener, Runnable { Runnable onAnimationEndRunnable = new Runnable() { @Override public void run() { - mLauncher.exitSpringLoadedDragMode(false, 0); + mLauncher.exitSpringLoadedDragMode(SPRING_LOADED_EXIT_NEXT_FRAME); mDropTarget.completeDrop(mDragObject); } }; diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java index b6b3089b0..61a733338 100644 --- a/src/com/android/launcher3/widget/BaseWidgetSheet.java +++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java @@ -15,6 +15,8 @@ */ package com.android.launcher3.widget; +import static com.android.launcher3.logging.LoggerUtils.newContainerTarget; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; @@ -32,7 +34,6 @@ import android.view.animation.DecelerateInterpolator; import android.widget.Toast; import com.android.launcher3.AbstractFloatingView; -import com.android.launcher3.DeleteDropTarget; import com.android.launcher3.DragSource; import com.android.launcher3.DropTarget.DragObject; import com.android.launcher3.ItemInfo; @@ -41,7 +42,6 @@ import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.dragndrop.DragOptions; -import com.android.launcher3.folder.Folder; import com.android.launcher3.graphics.GradientView; import com.android.launcher3.touch.SwipeDetector; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; @@ -264,11 +264,16 @@ abstract class BaseWidgetSheet extends AbstractFloatingView @Override public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) { targetParent.containerType = ContainerType.WIDGETS; + targetParent.cardinality = getElementsRowCount(); } @Override public final void logActionCommand(int command) { - // TODO: be more specific - mLauncher.getUserEventDispatcher().logActionCommand(command, ContainerType.WIDGETS); + Target target = newContainerTarget(ContainerType.WIDGETS); + target.cardinality = getElementsRowCount(); + mLauncher.getUserEventDispatcher().logActionCommand(command, target); } + + protected abstract int getElementsRowCount(); + } diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java index 201bd1c9c..3bb3fcb98 100644 --- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java +++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java @@ -181,4 +181,9 @@ public class WidgetsBottomSheet extends BaseWidgetSheet implements Insettable { setPadding(getPaddingLeft() + leftInset, getPaddingTop(), getPaddingRight() + rightInset, getPaddingBottom() + bottomInset); } + + @Override + protected int getElementsRowCount() { + return 1; + } } diff --git a/src/com/android/launcher3/widget/WidgetsFullSheet.java b/src/com/android/launcher3/widget/WidgetsFullSheet.java index 72277a253..a40ea1b64 100644 --- a/src/com/android/launcher3/widget/WidgetsFullSheet.java +++ b/src/com/android/launcher3/widget/WidgetsFullSheet.java @@ -219,4 +219,9 @@ public class WidgetsFullSheet extends BaseWidgetSheet sheet.open(animate); return sheet; } + + @Override + protected int getElementsRowCount() { + return mAdapter.getItemCount(); + } } |