diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2017-10-16 11:46:41 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2017-10-17 12:42:08 -0700 |
commit | aeb1643ec61af93453c862e84b158d3b0ebcb1c7 (patch) | |
tree | b57dcdc0892a153cb83333a2dab55547e7d87665 /src/com/android/launcher3/WorkspaceStateTransitionAnimation.java | |
parent | 1797af41d162413dc98c33fab8ba19f96b63874b (diff) | |
download | android_packages_apps_Trebuchet-aeb1643ec61af93453c862e84b158d3b0ebcb1c7.tar.gz android_packages_apps_Trebuchet-aeb1643ec61af93453c862e84b158d3b0ebcb1c7.tar.bz2 android_packages_apps_Trebuchet-aeb1643ec61af93453c862e84b158d3b0ebcb1c7.zip |
Launcher state management cleanup
> Removing Widgets and related states
> Fixing different durations being used when opening/closing all-apps
> Removing some unnecessary object allocations when changing state without animation
> Differentiating widget bootm sheel and full sheet in logs
Bug: 67678570
Change-Id: Ic169528736d04ee0b38564b4f96595ba066eabda
Diffstat (limited to 'src/com/android/launcher3/WorkspaceStateTransitionAnimation.java')
-rw-r--r-- | src/com/android/launcher3/WorkspaceStateTransitionAnimation.java | 426 |
1 files changed, 130 insertions, 296 deletions
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 |