diff --git a/src/com/android/launcher3/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java similarity index 80% rename from src/com/android/launcher3/states/AllAppsState.java rename to quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java index ed3023ab13..1064492000 100644 --- a/src/com/android/launcher3/states/AllAppsState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.android.launcher3.states; +package com.android.launcher3.uioverrides; import static com.android.launcher3.LauncherAnimUtils.ALL_APPS_TRANSITION_MS; +import static com.android.launcher3.allapps.DiscoveryBounce.APPS_VIEW_SHOWN; import android.view.View; @@ -30,8 +31,6 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; */ public class AllAppsState extends LauncherState { - public static final String APPS_VIEW_SHOWN = "launcher.apps_view_shown"; - private static final int STATE_FLAGS = FLAG_DISABLE_ACCESSIBILITY; public AllAppsState(int id) { @@ -57,4 +56,15 @@ public class AllAppsState extends LauncherState { public View getFinalFocus(Launcher launcher) { return launcher.getAppsView(); } + + @Override + public float[] getWorkspaceScaleAndTranslation(Launcher launcher) { + // TODO: interpolate + return LauncherState.OVERVIEW.getWorkspaceScaleAndTranslation(launcher); + } + + @Override + public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) { + return (i) -> 0; + } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java index a70ee70ffd..3458a3f9d7 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java @@ -17,10 +17,12 @@ package com.android.launcher3.uioverrides; import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS; +import android.graphics.Rect; import android.view.View; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; +import com.android.launcher3.Workspace; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.quickstep.RecentsView; @@ -29,7 +31,7 @@ import com.android.quickstep.RecentsView; */ public class OverviewState extends LauncherState { - private static final int STATE_FLAGS = FLAG_SHOW_SCRIM | FLAG_MULTI_PAGE + private static final int STATE_FLAGS = FLAG_SHOW_SCRIM | FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED; public OverviewState(int id) { @@ -38,8 +40,20 @@ public class OverviewState extends LauncherState { @Override public float[] getWorkspaceScaleAndTranslation(Launcher launcher) { - // TODO: Find a better transition - return new float[] {0f, 0}; + Rect pageRect = new Rect(); + RecentsView.getPageRect(launcher, pageRect); + Workspace ws = launcher.getWorkspace(); + float childWidth = ws.getNormalChildWidth(); + if (childWidth <= 0 || pageRect.isEmpty()) { + return super.getWorkspaceScaleAndTranslation(launcher); + } + + Rect insets = launcher.getDragLayer().getInsets(); + float scale = pageRect.width() / childWidth; + + float halfHeight = ws.getHeight() / 2; + float childTop = halfHeight - scale * (halfHeight - ws.getPaddingTop() - insets.top); + return new float[] {scale, pageRect.top - childTop}; } @Override diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index da1eff9741..b59e4ee2bd 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -15,39 +15,91 @@ */ package com.android.launcher3.uioverrides; -import static com.android.launcher3.WorkspaceStateTransitionAnimation.NO_ANIM_PROPERTY_SETTER; - +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.view.View; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherStateManager.AnimationConfig; import com.android.launcher3.LauncherStateManager.StateHandler; -import com.android.launcher3.WorkspaceStateTransitionAnimation.AnimatedPropertySetter; -import com.android.launcher3.WorkspaceStateTransitionAnimation.PropertySetter; import com.android.launcher3.anim.AnimationLayerSet; +import com.android.launcher3.anim.AnimationSuccessListener; +import com.android.launcher3.anim.Interpolators; +import com.android.quickstep.AnimatedFloat; +import com.android.quickstep.RecentsView; public class RecentsViewStateController implements StateHandler { private final Launcher mLauncher; + private final RecentsView mRecentsView; + + private final AnimatedFloat mTransitionProgress = new AnimatedFloat(this::applyProgress); + // The fraction representing the visibility of the RecentsView. This allows delaying the + // overall transition while the RecentsView is being shown or hidden. + private final AnimatedFloat mVisibilityMultiplier = new AnimatedFloat(this::applyProgress); public RecentsViewStateController(Launcher launcher) { mLauncher = launcher; + mRecentsView = launcher.getOverviewPanel(); + mRecentsView.setStateController(this); } @Override public void setState(LauncherState state) { - setState(state, NO_ANIM_PROPERTY_SETTER); + setVisibility(state == LauncherState.OVERVIEW); + setTransitionProgress(state == LauncherState.OVERVIEW ? 1 : 0); } @Override public void setStateWithAnimation(LauncherState toState, AnimationLayerSet layerViews, AnimatorSet anim, AnimationConfig config) { - setState(toState, new AnimatedPropertySetter(config.duration, layerViews, anim)); + ObjectAnimator progressAnim = + mTransitionProgress.animateToValue(toState == LauncherState.OVERVIEW ? 1 : 0); + progressAnim.setDuration(config.duration); + progressAnim.setInterpolator(Interpolators.LINEAR); + anim.play(progressAnim); + + ObjectAnimator visibilityAnim = animateVisibility(toState == LauncherState.OVERVIEW); + visibilityAnim.setDuration(config.duration); + visibilityAnim.setInterpolator(Interpolators.LINEAR); + anim.play(visibilityAnim); } - private void setState(LauncherState state, PropertySetter setter) { - setter.setViewAlpha(null, mLauncher.getOverviewPanel(), - state == LauncherState.OVERVIEW ? 1 : 0); + public void setVisibility(boolean isVisible) { + mVisibilityMultiplier.cancelAnimation(); + mRecentsView.setVisibility(isVisible ? View.VISIBLE : View.GONE); + mVisibilityMultiplier.updateValue(isVisible ? 1 : 0); + } + + public ObjectAnimator animateVisibility(boolean isVisible) { + ObjectAnimator anim = mVisibilityMultiplier.animateToValue(isVisible ? 1 : 0); + if (isVisible) { + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + mRecentsView.setVisibility(View.VISIBLE); + } + }); + } else { + anim.addListener(new AnimationSuccessListener() { + @Override + public void onAnimationSuccess(Animator animator) { + mRecentsView.setVisibility(View.GONE); + } + }); + } + return anim; + } + + public void setTransitionProgress(float progress) { + mTransitionProgress.cancelAnimation(); + mTransitionProgress.updateValue(progress); + } + + private void applyProgress() { + mRecentsView.setAlpha(mTransitionProgress.value * mVisibilityMultiplier.value); } } diff --git a/quickstep/src/com/android/quickstep/AnimatedFloat.java b/quickstep/src/com/android/quickstep/AnimatedFloat.java index 1f6781e2c5..214b3f3b9f 100644 --- a/quickstep/src/com/android/quickstep/AnimatedFloat.java +++ b/quickstep/src/com/android/quickstep/AnimatedFloat.java @@ -47,9 +47,7 @@ public class AnimatedFloat { } public ObjectAnimator animateToValue(float v) { - if (mValueAnimator != null) { - mValueAnimator.cancel(); - } + cancelAnimation(); mValueAnimator = ObjectAnimator.ofFloat(this, VALUE, v); mValueAnimator.addListener(new AnimatorListenerAdapter() { @Override @@ -73,6 +71,12 @@ public class AnimatedFloat { } } + public void cancelAnimation() { + if (mValueAnimator != null) { + mValueAnimator.cancel(); + } + } + public ObjectAnimator getCurrentAnimation() { return mValueAnimator; } diff --git a/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java b/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java index 4c3a9adcb4..75db45b837 100644 --- a/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java +++ b/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java @@ -42,6 +42,7 @@ import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.states.InternalStateHandler; +import com.android.launcher3.uioverrides.RecentsViewStateController; import com.android.launcher3.util.TraceHelper; import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan; import com.android.systemui.shared.recents.model.Task; @@ -94,6 +95,7 @@ public class NavBarSwipeInteractionHandler extends InternalStateHandler { private Launcher mLauncher; private SnapshotDragView mDragView; private RecentsView mRecentsView; + private RecentsViewStateController mStateController; private Hotseat mHotseat; private RecentsTaskLoadPlan mLoadPlan; @@ -178,11 +180,13 @@ public class NavBarSwipeInteractionHandler extends InternalStateHandler { mDragView.setPivotX(0); mDragView.setPivotY(0); mRecentsView = mLauncher.getOverviewPanel(); + mStateController = mRecentsView.getStateController(); mHotseat = mLauncher.getHotseat(); // Optimization mLauncher.getAppsView().setVisibility(View.GONE); - mRecentsView.setVisibility(View.GONE); + mStateController.setTransitionProgress(1); + mStateController.setVisibility(false); TraceHelper.partitionSection("TouchInt", "Launcher on new intent"); } @@ -209,17 +213,9 @@ public class NavBarSwipeInteractionHandler extends InternalStateHandler { } if (mTargetRect.isEmpty()) { + RecentsView.getPageRect(mLauncher, mTargetRect); DragLayer dl = mLauncher.getDragLayer(); mSourceRect.set(0, 0, dl.getWidth(), dl.getHeight()); - Rect targetPadding = RecentsView.getPadding(mLauncher); - Rect insets = dl.getInsets(); - mTargetRect.set( - targetPadding.left + insets.left, - targetPadding.top + insets.top, - mSourceRect.right - targetPadding.right - insets.right, - mSourceRect.bottom - targetPadding.bottom - insets.bottom); - mTargetRect.top += mLauncher.getResources() - .getDimensionPixelSize(R.dimen.task_thumbnail_top_margin); } float shift = mCurrentShift.value * mActivityMultiplier.value; @@ -246,12 +242,15 @@ public class NavBarSwipeInteractionHandler extends InternalStateHandler { private void setTaskPlanToUi() { mRecentsView.update(mLoadPlan); - mRecentsView.setVisibility(View.VISIBLE); - - // Animate alpha - mRecentsView.setAlpha(0); - mRecentsView.animate().alpha(1).setDuration(RECENTS_VIEW_VISIBILITY_DURATION) - .withEndAction(() -> mStateCallback.setState(STATE_RECENTS_FULLY_VISIBLE)); + ObjectAnimator anim = mStateController.animateVisibility(true /* isVisible */) + .setDuration(RECENTS_VIEW_VISIBILITY_DURATION); + anim.addListener(new AnimationSuccessListener() { + @Override + public void onAnimationSuccess(Animator animator) { + mStateCallback.setState(STATE_RECENTS_FULLY_VISIBLE); + } + }); + anim.start(); } @UiThread diff --git a/quickstep/src/com/android/quickstep/RecentsView.java b/quickstep/src/com/android/quickstep/RecentsView.java index 34ed7f19f2..c0fd2cfbc4 100644 --- a/quickstep/src/com/android/quickstep/RecentsView.java +++ b/quickstep/src/com/android/quickstep/RecentsView.java @@ -27,6 +27,8 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.PagedView; import com.android.launcher3.R; +import com.android.launcher3.dragndrop.DragLayer; +import com.android.launcher3.uioverrides.RecentsViewStateController; import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan; import com.android.systemui.shared.recents.model.RecentsTaskLoader; import com.android.systemui.shared.recents.model.Task; @@ -70,6 +72,8 @@ public class RecentsView extends PagedView { } }; + private RecentsViewStateController mStateController; + public RecentsView(Context context) { this(context, null); } @@ -111,6 +115,14 @@ public class RecentsView extends PagedView { updateTaskStackListenerState(); } + public void setStateController(RecentsViewStateController stateController) { + mStateController = stateController; + } + + public RecentsViewStateController getStateController() { + return mStateController; + } + public void setOverviewStateEnabled(boolean enabled) { mOverviewStateEnabled = enabled; updateTaskStackListenerState(); @@ -171,7 +183,7 @@ public class RecentsView extends PagedView { } } - public static Rect getPadding(Launcher launcher) { + private static Rect getPadding(Launcher launcher) { DeviceProfile profile = launcher.getDeviceProfile(); Rect stableInsets = new Rect(); WindowManagerWrapper.getInstance().getStableInsets(stableInsets); @@ -185,6 +197,19 @@ public class RecentsView extends PagedView { return padding; } + public static void getPageRect(Launcher launcher, Rect outRect) { + DragLayer dl = launcher.getDragLayer(); + Rect targetPadding = getPadding(launcher); + Rect insets = dl.getInsets(); + outRect.set( + targetPadding.left + insets.left, + targetPadding.top + insets.top, + dl.getWidth() - targetPadding.right - insets.right, + dl.getHeight() - targetPadding.bottom - insets.bottom); + outRect.top += launcher.getResources() + .getDimensionPixelSize(R.dimen.task_thumbnail_top_margin); + } + @Override public void computeScroll() { super.computeScroll(); diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 6b6029d3ae..a9b1619cde 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -1003,7 +1003,7 @@ public class Launcher extends BaseActivity int stateOrdinal = savedState.getInt(RUNTIME_STATE, NORMAL.ordinal); LauncherState[] stateValues = LauncherState.values(); LauncherState state = stateValues[stateOrdinal]; - if (!state.doNotRestore) { + if (!state.disableRestore) { mStateManager.goToState(state, false /* animated */); } diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java index 01d53dab59..dfb935fd43 100644 --- a/src/com/android/launcher3/LauncherState.java +++ b/src/com/android/launcher3/LauncherState.java @@ -21,7 +21,7 @@ import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CH import android.view.View; -import com.android.launcher3.states.AllAppsState; +import com.android.launcher3.uioverrides.AllAppsState; import com.android.launcher3.states.SpringLoadedState; import com.android.launcher3.uioverrides.OverviewState; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; @@ -37,13 +37,16 @@ public class LauncherState { protected static final int FLAG_SHOW_SCRIM = 1 << 0; protected static final int FLAG_MULTI_PAGE = 1 << 1; protected static final int FLAG_DISABLE_ACCESSIBILITY = 1 << 2; - protected static final int FLAG_DO_NOT_RESTORE = 1 << 3; + protected static final int FLAG_DISABLE_RESTORE = 1 << 3; protected static final int FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED = 1 << 4; + protected static final int FLAG_DISABLE_PAGE_CLIPPING = 1 << 5; + + protected static final PageAlphaProvider DEFAULT_ALPHA_PROVIDER = (i) -> 1f; private static final LauncherState[] sAllStates = new LauncherState[4]; public static final LauncherState NORMAL = new LauncherState(0, ContainerType.WORKSPACE, - 0, 1f, FLAG_DO_NOT_RESTORE | FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED); + 0, 1f, FLAG_DISABLE_RESTORE | FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED); public static final LauncherState ALL_APPS = new AllAppsState(1); @@ -61,7 +64,7 @@ public class LauncherState { /** * True if the state can be persisted across activity restarts. */ - public final boolean doNotRestore; + public final boolean disableRestore; /** * True if workspace has multiple pages visible. @@ -94,6 +97,12 @@ public class LauncherState { */ public final boolean workspaceIconsCanBeDragged; + /** + * True if the workspace pages should not be clipped relative to the workspace bounds + * for this state. + */ + public final boolean disablePageClipping; + public LauncherState(int id, int containerType, int transitionDuration, float verticalProgress, int flags) { this.containerType = containerType; @@ -104,8 +113,9 @@ public class LauncherState { this.workspaceAccessibilityFlag = (flags & FLAG_DISABLE_ACCESSIBILITY) != 0 ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS : IMPORTANT_FOR_ACCESSIBILITY_AUTO; - this.doNotRestore = (flags & FLAG_DO_NOT_RESTORE) != 0; + this.disableRestore = (flags & FLAG_DISABLE_RESTORE) != 0; this.workspaceIconsCanBeDragged = (flags & FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED) != 0; + this.disablePageClipping = (flags & FLAG_DISABLE_PAGE_CLIPPING) != 0; this.verticalProgress = verticalProgress; @@ -135,7 +145,20 @@ public class LauncherState { return launcher.getWorkspace().getCurrentPageDescription(); } + public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) { + if (this != NORMAL || !launcher.getDeviceProfile().shouldFadeAdjacentWorkspaceScreens()) { + return DEFAULT_ALPHA_PROVIDER; + } + int centerPage = launcher.getWorkspace().getPageNearestToCenterOfScreen(); + return (childIndex) -> childIndex != centerPage ? 0 : 1f; + } + protected static void dispatchWindowStateChanged(Launcher launcher) { launcher.getWindow().getDecorView().sendAccessibilityEvent(TYPE_WINDOW_STATE_CHANGED); } + + public interface PageAlphaProvider { + + float getPageAlpha(int pageIndex); + } } diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java index 1e6016b4d6..2cad95e9b8 100644 --- a/src/com/android/launcher3/LauncherStateManager.java +++ b/src/com/android/launcher3/LauncherStateManager.java @@ -158,14 +158,14 @@ public class LauncherStateManager { mConfig.reset(); if (!animated) { - setState(state); + onStateTransitionStart(state); for (StateHandler handler : getStateHandlers()) { handler.setState(state); } if (mStateListener != null) { mStateListener.onStateSetImmediately(state); } - mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); + onStateTransitionEnd(state); // Run any queued runnable if (onCompleteRunnable != null) { @@ -217,7 +217,7 @@ public class LauncherStateManager { @Override public void onAnimationStart(Animator animation) { // Change the internal state only when the transition actually starts - setState(state); + onStateTransitionStart(state); if (mStateListener != null) { mStateListener.onStateTransitionStart(state); } @@ -237,19 +237,28 @@ public class LauncherStateManager { if (onCompleteRunnable != null) { onCompleteRunnable.run(); } - - mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); + onStateTransitionEnd(state); } }); mConfig.setAnimation(animation); return mConfig.mCurrentAnimation; } - private void setState(LauncherState state) { + private void onStateTransitionStart(LauncherState state) { mState.onStateDisabled(mLauncher); mState = state; mState.onStateEnabled(mLauncher); mLauncher.getAppWidgetHost().setResumed(state == LauncherState.NORMAL); + + if (state.disablePageClipping) { + // Only disable clipping if needed, otherwise leave it as previous value. + mLauncher.getWorkspace().setClipChildren(false); + } + } + + private void onStateTransitionEnd(LauncherState state) { + mLauncher.getWorkspace().setClipChildren(!state.disablePageClipping); + mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); } /** diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index 9f6efb3701..b23568e9e9 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -593,6 +593,11 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc - mInsets.top - mInsets.bottom; } + public int getNormalChildWidth() { + return getViewportWidth() - getPaddingLeft() - getPaddingRight() + - mInsets.left - mInsets.right; + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (getChildCount() == 0) { diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 749afd08a0..3d59bad13b 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -192,10 +192,6 @@ public class Workspace extends PagedView private static final int HOTSEAT_STATE_ALPHA_INDEX = 2; - /** - * These values correspond to {@link Direction#X} & {@link Direction#Y} - */ - private final float[] mPageAlpha = new float[] {1, 1}; /** * Hotseat alpha can be changed when moving horizontally, vertically, changing states. * The values correspond to {@link Direction#X}, {@link Direction#Y} & @@ -436,7 +432,6 @@ public class Workspace extends PagedView mCurrentPage = DEFAULT_PAGE; DeviceProfile grid = mLauncher.getDeviceProfile(); setWillNotDraw(false); - setClipChildren(false); setClipToPadding(false); setupLayoutTransition(); @@ -1191,33 +1186,21 @@ public class Workspace extends PagedView // TODO(adamcohen): figure out a final effect here. We may need to recommend // different effects based on device performance. On at least one relatively high-end // device I've tried, translating the launcher causes things to get quite laggy. - setWorkspaceTranslationAndAlpha(Direction.X, transX, alpha); + setWorkspaceTranslationAndAlpha(transX, alpha); setHotseatTranslationAndAlpha(Direction.X, transX, alpha); } - /** - * Moves the workspace UI in the Y direction. - * @param translation the amount of shift. - * @param alpha the alpha for the workspace page - */ - public void setWorkspaceYTranslationAndAlpha(float translation, float alpha) { - setWorkspaceTranslationAndAlpha(Direction.Y, translation, alpha); - } - /** * Moves the workspace UI in the provided direction. - * @param direction the direction to move the workspace - * @param translation the amount of shift. + * @param translation the amount of horizontal shift. * @param alpha the alpha for the workspace page */ - private void setWorkspaceTranslationAndAlpha(Direction direction, float translation, float alpha) { - Property property = direction.viewProperty; - mPageAlpha[direction.ordinal()] = alpha; - float finalAlpha = mPageAlpha[0] * mPageAlpha[1]; + private void setWorkspaceTranslationAndAlpha(float translation, float alpha) { + float finalAlpha = alpha; View currentChild = getChildAt(getCurrentPage()); if (currentChild != null) { - property.set(currentChild, translation); + currentChild.setTranslationX(translation); currentChild.setAlpha(finalAlpha); } @@ -1225,7 +1208,7 @@ public class Workspace extends PagedView if (Float.compare(translation, 0) == 0) { for (int i = getChildCount() - 1; i >= 0; i--) { View child = getChildAt(i); - property.set(child, translation); + child.setTranslationX(0); child.setAlpha(finalAlpha); } } diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java index 8edec40d24..edf5ada6ec 100644 --- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java +++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java @@ -26,11 +26,11 @@ import android.animation.ObjectAnimator; 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.accessibility.AccessibilityManager; +import com.android.launcher3.LauncherState.PageAlphaProvider; import com.android.launcher3.LauncherStateManager.AnimationConfig; import com.android.launcher3.anim.AnimationLayerSet; import com.android.launcher3.anim.Interpolators; @@ -97,18 +97,13 @@ public class WorkspaceStateTransitionAnimation { private final Launcher mLauncher; private final Workspace mWorkspace; - private final boolean mWorkspaceFadeInAdjacentScreens; - private float mNewScale; public WorkspaceStateTransitionAnimation(Launcher launcher, Workspace workspace) { mLauncher = launcher; mWorkspace = workspace; - - DeviceProfile grid = mLauncher.getDeviceProfile(); - Resources res = launcher.getResources(); - mWorkspaceScrimAlpha = res.getInteger(R.integer.config_workspaceScrimAlpha); - mWorkspaceFadeInAdjacentScreens = grid.shouldFadeAdjacentWorkspaceScreens(); + mWorkspaceScrimAlpha = launcher.getResources() + .getInteger(R.integer.config_workspaceScrimAlpha); } public void setState(LauncherState toState) { @@ -134,10 +129,10 @@ public class WorkspaceStateTransitionAnimation { mNewScale = scaleAndTranslationY[0]; final float finalWorkspaceTranslationY = scaleAndTranslationY[1]; - int toPage = mWorkspace.getPageNearestToCenterOfScreen(); + PageAlphaProvider pageAlphaProvider = state.getWorkspacePageAlphaProvider(mLauncher); final int childCount = mWorkspace.getChildCount(); for (int i = 0; i < childCount; i++) { - applyChildState(state, (CellLayout) mWorkspace.getChildAt(i), i, toPage, + applyChildState(state, (CellLayout) mWorkspace.getChildAt(i), i, pageAlphaProvider, propertySetter); } @@ -151,21 +146,16 @@ public class WorkspaceStateTransitionAnimation { } public void applyChildState(LauncherState state, CellLayout cl, int childIndex) { - applyChildState(state, cl, childIndex, mWorkspace.getPageNearestToCenterOfScreen(), + applyChildState(state, cl, childIndex, state.getWorkspacePageAlphaProvider(mLauncher), NO_ANIM_PROPERTY_SETTER); } private void applyChildState(LauncherState state, CellLayout cl, int childIndex, - int centerPage, PropertySetter propertySetter) { + PageAlphaProvider pageAlphaProvider, PropertySetter propertySetter) { propertySetter.setInt(cl.getScrimBackground(), DRAWABLE_ALPHA, state.hasScrim ? 255 : 0, Interpolators.ZOOM_IN); - - // Only animate the page alpha when we actually fade pages - if (mWorkspaceFadeInAdjacentScreens) { - float finalAlpha = state == LauncherState.NORMAL && childIndex != centerPage ? 0 : 1f; - propertySetter.setFloat(cl.getShortcutsAndWidgets(), View.ALPHA, - finalAlpha, Interpolators.ZOOM_IN); - } + propertySetter.setFloat(cl.getShortcutsAndWidgets(), View.ALPHA, + pageAlphaProvider.getPageAlpha(childIndex), Interpolators.DEACCEL_2); } public static class PropertySetter { diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index 1ec7ac0b1e..7ce032f408 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -53,10 +53,9 @@ public class AllAppsTransitionController } }; - private final Interpolator mWorkspaceAccelnterpolator = Interpolators.ACCEL_2; private final Interpolator mHotseatAccelInterpolator = Interpolators.ACCEL_1_5; - private static final float PARALLAX_COEFFICIENT = .125f; + public static final float PARALLAX_COEFFICIENT = .125f; private AllAppsContainerView mAppsView; private Workspace mWorkspace; @@ -131,7 +130,6 @@ public class AllAppsTransitionController float workspaceHotseatAlpha = Utilities.boundToRange(progress, 0f, 1f); float alpha = 1 - workspaceHotseatAlpha; - float workspaceAlpha = mWorkspaceAccelnterpolator.getInterpolation(workspaceHotseatAlpha); float hotseatAlpha = mHotseatAccelInterpolator.getInterpolation(workspaceHotseatAlpha); updateAllAppsBg(alpha); @@ -146,8 +144,6 @@ public class AllAppsTransitionController PARALLAX_COEFFICIENT * (-mShiftRange + shiftCurrent), hotseatAlpha); } - mWorkspace.setWorkspaceYTranslationAndAlpha( - PARALLAX_COEFFICIENT * (-mShiftRange + shiftCurrent), workspaceAlpha); updateLightStatusBar(shiftCurrent); } diff --git a/src/com/android/launcher3/allapps/DiscoveryBounce.java b/src/com/android/launcher3/allapps/DiscoveryBounce.java index 9723545151..550fcf90a4 100644 --- a/src/com/android/launcher3/allapps/DiscoveryBounce.java +++ b/src/com/android/launcher3/allapps/DiscoveryBounce.java @@ -27,13 +27,14 @@ import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.compat.UserManagerCompat; -import com.android.launcher3.states.AllAppsState; /** * Floating view responsible for showing discovery bounce animation */ public class DiscoveryBounce extends AbstractFloatingView { + public static final String APPS_VIEW_SHOWN = "launcher.apps_view_shown"; + private final Launcher mLauncher; private final Animator mDiscoBounceAnimation; @@ -95,7 +96,7 @@ public class DiscoveryBounce extends AbstractFloatingView { public static void showIfNeeded(Launcher launcher) { if (!launcher.isInState(NORMAL) - || launcher.getSharedPrefs().getBoolean(AllAppsState.APPS_VIEW_SHOWN, false) + || launcher.getSharedPrefs().getBoolean(APPS_VIEW_SHOWN, false) || AbstractFloatingView.getTopOpenView(launcher) != null || UserManagerCompat.getInstance(launcher).isDemoUser()) { return; diff --git a/src/com/android/launcher3/states/SpringLoadedState.java b/src/com/android/launcher3/states/SpringLoadedState.java index 1d90a08bf7..995cdaa336 100644 --- a/src/com/android/launcher3/states/SpringLoadedState.java +++ b/src/com/android/launcher3/states/SpringLoadedState.java @@ -35,7 +35,8 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; public class SpringLoadedState extends LauncherState { private static final int STATE_FLAGS = FLAG_SHOW_SCRIM | FLAG_MULTI_PAGE | - FLAG_DISABLE_ACCESSIBILITY | FLAG_DO_NOT_RESTORE | FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED; + FLAG_DISABLE_ACCESSIBILITY | FLAG_DISABLE_RESTORE | FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED | + FLAG_DISABLE_PAGE_CLIPPING; // Determines how long to wait after a rotation before restoring the screen orientation to // match the sensor state. diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsState.java b/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsState.java new file mode 100644 index 0000000000..bd5ddfeaf1 --- /dev/null +++ b/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsState.java @@ -0,0 +1,72 @@ +/* + * 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.uioverrides; + +import static com.android.launcher3.LauncherAnimUtils.ALL_APPS_TRANSITION_MS; +import static com.android.launcher3.allapps.DiscoveryBounce.APPS_VIEW_SHOWN; + +import android.view.View; + +import com.android.launcher3.AbstractFloatingView; +import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherState; +import com.android.launcher3.R; +import com.android.launcher3.allapps.AllAppsTransitionController; +import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; + +/** + * Definition for AllApps state + */ +public class AllAppsState extends LauncherState { + + private static final int STATE_FLAGS = FLAG_DISABLE_ACCESSIBILITY; + + public AllAppsState(int id) { + super(id, ContainerType.ALLAPPS, ALL_APPS_TRANSITION_MS, 0f, STATE_FLAGS); + } + + @Override + public void onStateEnabled(Launcher launcher) { + if (!launcher.getSharedPrefs().getBoolean(APPS_VIEW_SHOWN, false)) { + launcher.getSharedPrefs().edit().putBoolean(APPS_VIEW_SHOWN, true).apply(); + } + + AbstractFloatingView.closeAllOpenViews(launcher); + dispatchWindowStateChanged(launcher); + } + + @Override + public String getDescription(Launcher launcher) { + return launcher.getString(R.string.all_apps_button_label); + } + + @Override + public View getFinalFocus(Launcher launcher) { + return launcher.getAppsView(); + } + + @Override + public float[] getWorkspaceScaleAndTranslation(Launcher launcher) { + return new float[] { 1f, + -launcher.getAllAppsController().getShiftRange() + * AllAppsTransitionController.PARALLAX_COEFFICIENT}; + } + + @Override + public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) { + return (i) -> 0; + } +} diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/OverviewState.java b/src_ui_overrides/com/android/launcher3/uioverrides/OverviewState.java index dcf7453b9e..2cd3731d4d 100644 --- a/src_ui_overrides/com/android/launcher3/uioverrides/OverviewState.java +++ b/src_ui_overrides/com/android/launcher3/uioverrides/OverviewState.java @@ -36,7 +36,8 @@ public class OverviewState extends LauncherState { // The percent to shrink the workspace during overview mode private static final float SCALE_FACTOR = 0.7f; - private static final int STATE_FLAGS = FLAG_SHOW_SCRIM | FLAG_MULTI_PAGE; + private static final int STATE_FLAGS = FLAG_SHOW_SCRIM | FLAG_MULTI_PAGE | + FLAG_DISABLE_PAGE_CLIPPING; public OverviewState(int id) { super(id, ContainerType.WORKSPACE, OVERVIEW_TRANSITION_MS, 1f, STATE_FLAGS);