Separating various UI properties into state variables
> Using workspace scale and translation for all-apps
> Without quickstep, workspace has the parallex effect as before
> With quickstep, workspace scales down to match the recents card width
> Using a single animator for recents views in case of state transtion and
controlled transition to prevent going into inconsistant state.
Change-Id: I1864de6892052ca771f4d0062e3d60c28840a72d
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 6b6029d..a9b1619 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1003,7 +1003,7 @@
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 01d53da..dfb935f 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -21,7 +21,7 @@
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 @@
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 @@
/**
* 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 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 @@
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 @@
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 1e6016b..2cad95e 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -158,14 +158,14 @@
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 @@
@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 @@
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 9f6efb3..b23568e 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -593,6 +593,11 @@
- 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 749afd0..3d59bad 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -193,10 +193,6 @@
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} &
* {@link #HOTSEAT_STATE_ALPHA_INDEX} respectively.
@@ -436,7 +432,6 @@
mCurrentPage = DEFAULT_PAGE;
DeviceProfile grid = mLauncher.getDeviceProfile();
setWillNotDraw(false);
- setClipChildren(false);
setClipToPadding(false);
setupLayoutTransition();
@@ -1191,33 +1186,21 @@
// 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<View, Float> 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 @@
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 8edec40..edf5ada 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -26,11 +26,11 @@
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 @@
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 @@
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 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 1ec7ac0..7ce032f 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -53,10 +53,9 @@
}
};
- 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 @@
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 @@
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 9723545..550fcf9 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.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 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/AllAppsState.java b/src/com/android/launcher3/states/AllAppsState.java
deleted file mode 100644
index ed3023a..0000000
--- a/src/com/android/launcher3/states/AllAppsState.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.states;
-
-import static com.android.launcher3.LauncherAnimUtils.ALL_APPS_TRANSITION_MS;
-
-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.userevent.nano.LauncherLogProto.ContainerType;
-
-/**
- * Definition for AllApps state
- */
-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) {
- 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();
- }
-}
diff --git a/src/com/android/launcher3/states/SpringLoadedState.java b/src/com/android/launcher3/states/SpringLoadedState.java
index 1d90a08..995cdaa 100644
--- a/src/com/android/launcher3/states/SpringLoadedState.java
+++ b/src/com/android/launcher3/states/SpringLoadedState.java
@@ -35,7 +35,8 @@
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.