Merge "Refactoring to single path for overview mode." into ub-launcher3-burnaby
This commit is contained in:
@@ -6,10 +6,6 @@
|
||||
<!-- Out of 100, the percent to shrink the workspace during spring loaded mode. -->
|
||||
<integer name="config_workspaceSpringLoadShrinkPercentage">90</integer>
|
||||
|
||||
<!-- Workspace -->
|
||||
<!-- Whether or not the drop targets drop down as opposed to fade in -->
|
||||
<bool name="config_useDropTargetDownTransition">false</bool>
|
||||
|
||||
<!-- Hotseat -->
|
||||
<bool name="hotseat_transpose_layout_with_orientation">false</bool>
|
||||
</resources>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<!-- AllApps/Customize/AppsCustomize -->
|
||||
<!-- The alpha of the AppsCustomize bg in spring loaded mode -->
|
||||
<integer name="config_workspaceScrimAlpha">55</integer>
|
||||
<integer name="config_workspaceUnshrinkTime">300</integer>
|
||||
<integer name="config_workspaceUnshrinkTime">100</integer>
|
||||
<integer name="config_overviewTransitionTime">250</integer>
|
||||
|
||||
<!-- Out of 100, the percent to shrink the workspace during spring loaded mode. -->
|
||||
@@ -55,9 +55,6 @@
|
||||
<integer name="config_appsCustomizeDragSlopeThreshold">150</integer>
|
||||
|
||||
<!-- Workspace -->
|
||||
<!-- Whether or not the drop targets drop down as opposed to fade in -->
|
||||
<bool name="config_useDropTargetDownTransition">false</bool>
|
||||
|
||||
<!-- The transition duration for the background of the drop targets -->
|
||||
<integer name="config_dropTargetBgTransitionDuration">0</integer>
|
||||
|
||||
|
||||
@@ -214,7 +214,6 @@ public class Launcher extends Activity
|
||||
/** The different states that Launcher can be in. */
|
||||
enum State { NONE, WORKSPACE, APPS, APPS_SPRING_LOADED, WIDGETS, WIDGETS_SPRING_LOADED };
|
||||
@Thunk State mState = State.WORKSPACE;
|
||||
@Thunk AnimatorSet mStateAnimation;
|
||||
@Thunk LauncherStateTransitionAnimation mStateTransitionAnimation;
|
||||
|
||||
private boolean mIsSafeModeEnabled;
|
||||
@@ -528,7 +527,8 @@ public class Launcher extends Activity
|
||||
|
||||
@Override
|
||||
public void dismissAllApps() {
|
||||
showWorkspace(true);
|
||||
showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, true, null,
|
||||
false /* notifyLauncherCallbacks */);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
@@ -785,7 +785,7 @@ public class Launcher extends Activity
|
||||
return;
|
||||
} else if (requestCode == REQUEST_PICK_WALLPAPER) {
|
||||
if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {
|
||||
mWorkspace.exitOverviewMode(false);
|
||||
showWorkspace(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1220,7 +1220,6 @@ public class Launcher extends Activity
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public void addToCustomContentPage(View customContent,
|
||||
CustomContentCallbacks callbacks, String description) {
|
||||
mWorkspace.addToCustomContentPage(customContent, callbacks, description);
|
||||
@@ -2480,7 +2479,7 @@ public class Launcher extends Activity
|
||||
} else if (isWidgetsViewVisible()) {
|
||||
showOverviewMode(true);
|
||||
} else if (mWorkspace.isInOverviewMode()) {
|
||||
mWorkspace.exitOverviewMode(true);
|
||||
showWorkspace(true);
|
||||
} else if (mWorkspace.getOpenFolder() != null) {
|
||||
Folder openFolder = mWorkspace.getOpenFolder();
|
||||
if (openFolder.isEditingName()) {
|
||||
@@ -2523,14 +2522,14 @@ public class Launcher extends Activity
|
||||
|
||||
if (v instanceof Workspace) {
|
||||
if (mWorkspace.isInOverviewMode()) {
|
||||
mWorkspace.exitOverviewMode(true);
|
||||
showWorkspace(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (v instanceof CellLayout) {
|
||||
if (mWorkspace.isInOverviewMode()) {
|
||||
mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);
|
||||
showWorkspace(mWorkspace.indexOfChild(v), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3178,7 +3177,9 @@ public class Launcher extends Activity
|
||||
|
||||
if (v instanceof Workspace) {
|
||||
if (!mWorkspace.isInOverviewMode()) {
|
||||
if (mWorkspace.enterOverviewMode()) {
|
||||
|
||||
if (!mWorkspace.isTouchActive()) {
|
||||
showOverviewMode(true);
|
||||
mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
|
||||
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
|
||||
return true;
|
||||
@@ -3211,7 +3212,7 @@ public class Launcher extends Activity
|
||||
if (mWorkspace.isInOverviewMode()) {
|
||||
mWorkspace.startReordering(v);
|
||||
} else {
|
||||
mWorkspace.enterOverviewMode();
|
||||
showOverviewMode(true);
|
||||
}
|
||||
} else {
|
||||
final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(
|
||||
@@ -3302,17 +3303,28 @@ public class Launcher extends Activity
|
||||
}
|
||||
|
||||
protected void showWorkspace(boolean animated) {
|
||||
showWorkspace(animated, null);
|
||||
showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated, null,
|
||||
true);
|
||||
}
|
||||
|
||||
void showWorkspace(boolean animated, Runnable onCompleteRunnable) {
|
||||
protected void showWorkspace(boolean animated, Runnable onCompleteRunnable) {
|
||||
showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated,
|
||||
onCompleteRunnable, true);
|
||||
}
|
||||
|
||||
protected void showWorkspace(int snapToPage, boolean animated) {
|
||||
showWorkspace(snapToPage, animated, null, true);
|
||||
}
|
||||
|
||||
void showWorkspace(int snapToPage, boolean animated, Runnable onCompleteRunnable,
|
||||
boolean notifyLauncherCallbacks) {
|
||||
boolean changed = mState != State.WORKSPACE ||
|
||||
mWorkspace.getState() != Workspace.State.NORMAL;
|
||||
if (changed) {
|
||||
boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);
|
||||
mWorkspace.setVisibility(View.VISIBLE);
|
||||
mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.NORMAL,
|
||||
animated, onCompleteRunnable);
|
||||
snapToPage, animated, onCompleteRunnable);
|
||||
|
||||
// Show the search bar (only animate if we were showing the drop target bar in spring
|
||||
// loaded mode)
|
||||
@@ -3345,7 +3357,8 @@ public class Launcher extends Activity
|
||||
void showOverviewMode(boolean animated) {
|
||||
mWorkspace.setVisibility(View.VISIBLE);
|
||||
mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.OVERVIEW,
|
||||
animated, null /* onCompleteRunnable */);
|
||||
WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated,
|
||||
null /* onCompleteRunnable */);
|
||||
mState = State.WORKSPACE;
|
||||
onWorkspaceShown(animated);
|
||||
}
|
||||
@@ -3419,7 +3432,8 @@ public class Launcher extends Activity
|
||||
}
|
||||
|
||||
mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.SPRING_LOADED,
|
||||
true /* animated */, null /* onCompleteRunnable */);
|
||||
WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, true /* animated */,
|
||||
null /* onCompleteRunnable */);
|
||||
mState = isAppsViewVisible() ? State.APPS_SPRING_LOADED : State.WIDGETS_SPRING_LOADED;
|
||||
}
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ class LauncherClings implements OnClickListener {
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
mLauncher.getWorkspace().enterOverviewMode();
|
||||
mLauncher.showOverviewMode(true);
|
||||
dismissLongPressCling();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.content.res.Resources;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewAnimationUtils;
|
||||
@@ -174,7 +173,8 @@ public class LauncherStateTransitionAnimation {
|
||||
}
|
||||
};
|
||||
startAnimationToOverlay(Workspace.State.NORMAL_HIDDEN, toView, toView.getContentView(),
|
||||
toView.getRevealView(), animated, false /* hideSearchBar */, cb);
|
||||
toView.getRevealView(), animated,
|
||||
!mLauncher.isAllAppsSearchOverridden() /* hideSearchBar */, cb);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -207,8 +207,8 @@ public class LauncherStateTransitionAnimation {
|
||||
* Starts and animation to the workspace from the current overlay view.
|
||||
*/
|
||||
public void startAnimationToWorkspace(final Launcher.State fromState,
|
||||
final Workspace.State toWorkspaceState, final boolean animated,
|
||||
final Runnable onCompleteRunnable) {
|
||||
final Workspace.State toWorkspaceState, final int toWorkspacePage,
|
||||
final boolean animated, final Runnable onCompleteRunnable) {
|
||||
if (toWorkspaceState != Workspace.State.NORMAL &&
|
||||
toWorkspaceState != Workspace.State.SPRING_LOADED &&
|
||||
toWorkspaceState != Workspace.State.OVERVIEW) {
|
||||
@@ -216,11 +216,11 @@ public class LauncherStateTransitionAnimation {
|
||||
}
|
||||
|
||||
if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED) {
|
||||
startAnimationToWorkspaceFromAllApps(fromState, toWorkspaceState, animated,
|
||||
onCompleteRunnable);
|
||||
startAnimationToWorkspaceFromAllApps(fromState, toWorkspaceState, toWorkspacePage,
|
||||
animated, onCompleteRunnable);
|
||||
} else {
|
||||
startAnimationToWorkspaceFromWidgets(fromState, toWorkspaceState, animated,
|
||||
onCompleteRunnable);
|
||||
startAnimationToWorkspaceFromWidgets(fromState, toWorkspaceState, toWorkspacePage,
|
||||
animated, onCompleteRunnable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,8 +249,8 @@ public class LauncherStateTransitionAnimation {
|
||||
|
||||
// Create the workspace animation.
|
||||
// NOTE: this call apparently also sets the state for the workspace if !animated
|
||||
Animator workspaceAnim = mLauncher.getWorkspace().getChangeStateAnimation(
|
||||
toWorkspaceState, animated, layerViews);
|
||||
Animator workspaceAnim = mLauncher.getWorkspace().setStateWithAnimation(
|
||||
toWorkspaceState, -1, animated, layerViews);
|
||||
|
||||
if (animated && initialized) {
|
||||
mStateAnimation = LauncherAnimUtils.createAnimatorSet();
|
||||
@@ -424,8 +424,8 @@ public class LauncherStateTransitionAnimation {
|
||||
* Starts and animation to the workspace from the apps view.
|
||||
*/
|
||||
private void startAnimationToWorkspaceFromAllApps(final Launcher.State fromState,
|
||||
final Workspace.State toWorkspaceState, final boolean animated,
|
||||
final Runnable onCompleteRunnable) {
|
||||
final Workspace.State toWorkspaceState, final int toWorkspacePage,
|
||||
final boolean animated, final Runnable onCompleteRunnable) {
|
||||
AppsContainerView appsView = mLauncher.getAppsView();
|
||||
PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
|
||||
int[] mAllAppsToPanelDelta;
|
||||
@@ -477,16 +477,17 @@ public class LauncherStateTransitionAnimation {
|
||||
};
|
||||
}
|
||||
};
|
||||
startAnimationToWorkspaceFromOverlay(toWorkspaceState, appsView, appsView.getContentView(),
|
||||
appsView.getRevealView(), animated, onCompleteRunnable, cb);
|
||||
startAnimationToWorkspaceFromOverlay(toWorkspaceState, toWorkspacePage, appsView,
|
||||
appsView.getContentView(), appsView.getRevealView(), animated, onCompleteRunnable,
|
||||
cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts and animation to the workspace from the widgets view.
|
||||
*/
|
||||
private void startAnimationToWorkspaceFromWidgets(final Launcher.State fromState,
|
||||
final Workspace.State toWorkspaceState, final boolean animated,
|
||||
final Runnable onCompleteRunnable) {
|
||||
final Workspace.State toWorkspaceState, final int toWorkspacePage,
|
||||
final boolean animated, final Runnable onCompleteRunnable) {
|
||||
final WidgetsContainerView widgetsView = mLauncher.getWidgetsView();
|
||||
final Resources res = mLauncher.getResources();
|
||||
PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
|
||||
@@ -514,7 +515,7 @@ public class LauncherStateTransitionAnimation {
|
||||
};
|
||||
}
|
||||
};
|
||||
startAnimationToWorkspaceFromOverlay(toWorkspaceState, widgetsView,
|
||||
startAnimationToWorkspaceFromOverlay(toWorkspaceState, toWorkspacePage, widgetsView,
|
||||
widgetsView.getContentView(), widgetsView.getRevealView(), animated,
|
||||
onCompleteRunnable, cb);
|
||||
}
|
||||
@@ -523,8 +524,8 @@ public class LauncherStateTransitionAnimation {
|
||||
* Creates and starts a new animation to the workspace.
|
||||
*/
|
||||
private void startAnimationToWorkspaceFromOverlay(final Workspace.State toWorkspaceState,
|
||||
final View fromView, final View contentView, final View revealView,
|
||||
final boolean animated, final Runnable onCompleteRunnable,
|
||||
final int toWorkspacePage, final View fromView, final View contentView,
|
||||
final View revealView, final boolean animated, final Runnable onCompleteRunnable,
|
||||
final PrivateTransitionCallbacks pCb) {
|
||||
final Resources res = mLauncher.getResources();
|
||||
final boolean material = Utilities.isLmpOrAbove();
|
||||
@@ -545,8 +546,8 @@ public class LauncherStateTransitionAnimation {
|
||||
|
||||
// Create the workspace animation.
|
||||
// NOTE: this call apparently also sets the state for the workspace if !animated
|
||||
Animator workspaceAnim = mLauncher.getWorkspace().getChangeStateAnimation(
|
||||
toWorkspaceState, animated, layerViews);
|
||||
Animator workspaceAnim = mLauncher.getWorkspace().setStateWithAnimation(
|
||||
toWorkspaceState, toWorkspacePage, animated, layerViews);
|
||||
|
||||
if (animated && initialized) {
|
||||
mStateAnimation = LauncherAnimUtils.createAnimatorSet();
|
||||
|
||||
@@ -1696,11 +1696,11 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
||||
return OVERSCROLL_DAMP_FACTOR * f;
|
||||
}
|
||||
|
||||
protected void enableFreeScroll() {
|
||||
public void enableFreeScroll() {
|
||||
setEnableFreeScroll(true);
|
||||
}
|
||||
|
||||
protected void disableFreeScroll() {
|
||||
public void disableFreeScroll() {
|
||||
setEnableFreeScroll(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,18 +33,16 @@ import android.widget.FrameLayout;
|
||||
*/
|
||||
public class SearchDropTargetBar extends FrameLayout implements DragController.DragListener {
|
||||
|
||||
private static final int sTransitionInDuration = 200;
|
||||
private static final int sTransitionOutDuration = 175;
|
||||
private static final int TRANSITION_DURATION = 200;
|
||||
|
||||
private ObjectAnimator mDropTargetBarAnim;
|
||||
private ValueAnimator mQSBSearchBarAnim;
|
||||
private ObjectAnimator mShowDropTargetBarAnim;
|
||||
private ValueAnimator mHideSearchBarAnim;
|
||||
private static final AccelerateInterpolator sAccelerateInterpolator =
|
||||
new AccelerateInterpolator();
|
||||
|
||||
private boolean mIsSearchBarHidden;
|
||||
private View mQSBSearchBar;
|
||||
private View mDropTargetBar;
|
||||
private int mBarHeight;
|
||||
private boolean mDeferOnDragEnd = false;
|
||||
|
||||
// Drop targets
|
||||
@@ -52,8 +50,6 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
|
||||
private ButtonDropTarget mDeleteDropTarget;
|
||||
private ButtonDropTarget mUninstallDropTarget;
|
||||
|
||||
private boolean mEnableDropDownDropTargets;
|
||||
|
||||
public SearchDropTargetBar(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
@@ -82,17 +78,12 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
|
||||
public void setQsbSearchBar(View qsb) {
|
||||
mQSBSearchBar = qsb;
|
||||
if (mQSBSearchBar != null) {
|
||||
if (mEnableDropDownDropTargets) {
|
||||
mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "translationY", 0,
|
||||
-mBarHeight);
|
||||
} else {
|
||||
mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "alpha", 1f, 0f);
|
||||
}
|
||||
setupAnimation(mQSBSearchBarAnim, mQSBSearchBar);
|
||||
mHideSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "alpha", 1f, 0f);
|
||||
setupAnimation(mHideSearchBarAnim, mQSBSearchBar);
|
||||
} else {
|
||||
// Create a no-op animation of the search bar is null
|
||||
mQSBSearchBarAnim = ValueAnimator.ofFloat(0, 0);
|
||||
mQSBSearchBarAnim.setDuration(sTransitionInDuration);
|
||||
mHideSearchBarAnim = ValueAnimator.ofFloat(0, 0);
|
||||
mHideSearchBarAnim.setDuration(TRANSITION_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +97,7 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
|
||||
|
||||
private void setupAnimation(ValueAnimator anim, final View v) {
|
||||
anim.setInterpolator(sAccelerateInterpolator);
|
||||
anim.setDuration(sTransitionInDuration);
|
||||
anim.setDuration(TRANSITION_DURATION);
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
@@ -131,76 +122,74 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
|
||||
mDeleteDropTarget.setSearchDropTargetBar(this);
|
||||
mUninstallDropTarget.setSearchDropTargetBar(this);
|
||||
|
||||
mEnableDropDownDropTargets =
|
||||
getResources().getBoolean(R.bool.config_useDropTargetDownTransition);
|
||||
|
||||
// Create the various fade animations
|
||||
if (mEnableDropDownDropTargets) {
|
||||
LauncherAppState app = LauncherAppState.getInstance();
|
||||
DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
|
||||
mBarHeight = grid.searchBarSpaceHeightPx;
|
||||
mDropTargetBar.setTranslationY(-mBarHeight);
|
||||
mDropTargetBarAnim = LauncherAnimUtils.ofFloat(mDropTargetBar, "translationY",
|
||||
-mBarHeight, 0f);
|
||||
|
||||
} else {
|
||||
mDropTargetBar.setAlpha(0f);
|
||||
mDropTargetBarAnim = LauncherAnimUtils.ofFloat(mDropTargetBar, "alpha", 0f, 1f);
|
||||
}
|
||||
setupAnimation(mDropTargetBarAnim, mDropTargetBar);
|
||||
mDropTargetBar.setAlpha(0f);
|
||||
mShowDropTargetBarAnim = LauncherAnimUtils.ofFloat(mDropTargetBar, "alpha", 0f, 1f);
|
||||
setupAnimation(mShowDropTargetBarAnim, mDropTargetBar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes all the animations on the search and drop target bars.
|
||||
*/
|
||||
public void finishAnimations() {
|
||||
prepareStartAnimation(mDropTargetBar);
|
||||
mDropTargetBarAnim.reverse();
|
||||
mShowDropTargetBarAnim.reverse();
|
||||
prepareStartAnimation(mQSBSearchBar);
|
||||
mQSBSearchBarAnim.reverse();
|
||||
mHideSearchBarAnim.reverse();
|
||||
}
|
||||
|
||||
/*
|
||||
* Shows and hides the search bar.
|
||||
/**
|
||||
* Shows the search bar.
|
||||
*/
|
||||
public void showSearchBar(boolean animated) {
|
||||
boolean needToCancelOngoingAnimation = mQSBSearchBarAnim.isRunning() && !animated;
|
||||
if (!mIsSearchBarHidden && !needToCancelOngoingAnimation) return;
|
||||
if (!mIsSearchBarHidden) return;
|
||||
if (animated) {
|
||||
prepareStartAnimation(mQSBSearchBar);
|
||||
mQSBSearchBarAnim.reverse();
|
||||
mHideSearchBarAnim.reverse();
|
||||
} else {
|
||||
mQSBSearchBarAnim.cancel();
|
||||
if (mQSBSearchBar != null && mEnableDropDownDropTargets) {
|
||||
mQSBSearchBar.setTranslationY(0);
|
||||
} else if (mQSBSearchBar != null) {
|
||||
mHideSearchBarAnim.cancel();
|
||||
if (mQSBSearchBar != null) {
|
||||
mQSBSearchBar.setAlpha(1f);
|
||||
}
|
||||
}
|
||||
mIsSearchBarHidden = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the search bar. We only use this for clings.
|
||||
*/
|
||||
public void hideSearchBar(boolean animated) {
|
||||
boolean needToCancelOngoingAnimation = mQSBSearchBarAnim.isRunning() && !animated;
|
||||
if (mIsSearchBarHidden && !needToCancelOngoingAnimation) return;
|
||||
if (mIsSearchBarHidden) return;
|
||||
if (animated) {
|
||||
prepareStartAnimation(mQSBSearchBar);
|
||||
mQSBSearchBarAnim.start();
|
||||
mHideSearchBarAnim.start();
|
||||
} else {
|
||||
mQSBSearchBarAnim.cancel();
|
||||
if (mQSBSearchBar != null && mEnableDropDownDropTargets) {
|
||||
mQSBSearchBar.setTranslationY(-mBarHeight);
|
||||
} else if (mQSBSearchBar != null) {
|
||||
mHideSearchBarAnim.cancel();
|
||||
if (mQSBSearchBar != null) {
|
||||
mQSBSearchBar.setAlpha(0f);
|
||||
}
|
||||
}
|
||||
mIsSearchBarHidden = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets various transition durations.
|
||||
/**
|
||||
* Shows the drop target bar.
|
||||
*/
|
||||
public int getTransitionInDuration() {
|
||||
return sTransitionInDuration;
|
||||
public void showDeleteTarget() {
|
||||
// Animate out the QSB search bar, and animate in the drop target bar
|
||||
prepareStartAnimation(mDropTargetBar);
|
||||
mShowDropTargetBarAnim.start();
|
||||
hideSearchBar(true);
|
||||
}
|
||||
public int getTransitionOutDuration() {
|
||||
return sTransitionOutDuration;
|
||||
|
||||
/**
|
||||
* Hides the drop target bar.
|
||||
*/
|
||||
public void hideDeleteTarget() {
|
||||
// Restore the QSB search bar, and animate out the drop target bar
|
||||
prepareStartAnimation(mDropTargetBar);
|
||||
mShowDropTargetBarAnim.reverse();
|
||||
showSearchBar(true);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -211,26 +200,6 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
|
||||
showDeleteTarget();
|
||||
}
|
||||
|
||||
public void showDeleteTarget() {
|
||||
// Animate out the QSB search bar, and animate in the drop target bar
|
||||
prepareStartAnimation(mDropTargetBar);
|
||||
mDropTargetBarAnim.start();
|
||||
if (!mIsSearchBarHidden) {
|
||||
prepareStartAnimation(mQSBSearchBar);
|
||||
mQSBSearchBarAnim.start();
|
||||
}
|
||||
}
|
||||
|
||||
public void hideDeleteTarget() {
|
||||
// Restore the QSB search bar, and animate out the drop target bar
|
||||
prepareStartAnimation(mDropTargetBar);
|
||||
mDropTargetBarAnim.reverse();
|
||||
if (!mIsSearchBarHidden) {
|
||||
prepareStartAnimation(mQSBSearchBar);
|
||||
mQSBSearchBarAnim.reverse();
|
||||
}
|
||||
}
|
||||
|
||||
public void deferOnDragEnd() {
|
||||
mDeferOnDragEnd = true;
|
||||
}
|
||||
|
||||
@@ -17,15 +17,10 @@
|
||||
package com.android.launcher3;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.Animator.AnimatorListener;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.LayoutTransition;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.animation.ValueAnimator.AnimatorUpdateListener;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.WallpaperManager;
|
||||
import android.appwidget.AppWidgetHostView;
|
||||
@@ -99,12 +94,9 @@ public class Workspace extends SmoothPagedView
|
||||
protected static final int SNAP_OFF_EMPTY_SCREEN_DURATION = 400;
|
||||
protected static final int FADE_EMPTY_SCREEN_DURATION = 150;
|
||||
|
||||
private static final int BACKGROUND_FADE_OUT_DURATION = 350;
|
||||
private static final int ADJACENT_SCREEN_DROP_DURATION = 300;
|
||||
private static final int FLING_THRESHOLD_VELOCITY = 500;
|
||||
|
||||
private static final float ALPHA_CUTOFF_THRESHOLD = 0.01f;
|
||||
|
||||
static final boolean MAP_NO_RECURSE = false;
|
||||
static final boolean MAP_RECURSE = true;
|
||||
|
||||
@@ -113,10 +105,6 @@ public class Workspace extends SmoothPagedView
|
||||
private ObjectAnimator mChildrenOutlineFadeOutAnimation;
|
||||
private float mChildrenOutlineAlpha = 0;
|
||||
|
||||
// These properties refer to the background protection gradient used for AllApps and Customize
|
||||
private ValueAnimator mBackgroundFadeInAnimation;
|
||||
private ValueAnimator mBackgroundFadeOutAnimation;
|
||||
|
||||
private static final long CUSTOM_CONTENT_GESTURE_DELAY = 200;
|
||||
private long mTouchDownTime = -1;
|
||||
private long mCustomContentShowTime = -1;
|
||||
@@ -129,7 +117,6 @@ public class Workspace extends SmoothPagedView
|
||||
private int mDefaultPage;
|
||||
|
||||
private ShortcutAndWidgetContainer mDragSourceInternal;
|
||||
@Thunk static boolean sAccessibilityEnabled;
|
||||
|
||||
// The screen id used for the empty screen always present to the right.
|
||||
final static long EXTRA_EMPTY_SCREEN_ID = -201;
|
||||
@@ -272,14 +259,7 @@ public class Workspace extends SmoothPagedView
|
||||
private float mSavedTranslationX;
|
||||
|
||||
private float mCurrentScale;
|
||||
private float mNewScale;
|
||||
@Thunk float[] mOldBackgroundAlphas;
|
||||
private float[] mOldAlphas;
|
||||
@Thunk float[] mNewBackgroundAlphas;
|
||||
private float[] mNewAlphas;
|
||||
private int mLastChildCount = -1;
|
||||
private float mTransitionProgress;
|
||||
@Thunk Animator mStateAnimator = null;
|
||||
|
||||
float mOverScrollEffect = 0f;
|
||||
|
||||
@@ -294,6 +274,9 @@ public class Workspace extends SmoothPagedView
|
||||
boolean mShouldSendPageSettled;
|
||||
int mLastOverlaySroll = 0;
|
||||
|
||||
// Handles workspace state transitions
|
||||
private WorkspaceStateTransitionAnimation mStateTransitionAnimation;
|
||||
|
||||
private final Runnable mBindPages = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -329,6 +312,7 @@ public class Workspace extends SmoothPagedView
|
||||
setDataIsReady();
|
||||
|
||||
mLauncher = (Launcher) context;
|
||||
mStateTransitionAnimation = new WorkspaceStateTransitionAnimation(mLauncher, this);
|
||||
final Resources res = getResources();
|
||||
mWorkspaceFadeInAdjacentScreens = LauncherAppState.getInstance().getDynamicGrid().
|
||||
getDeviceProfile().shouldFadeAdjacentWorkspaceScreens();
|
||||
@@ -1583,37 +1567,6 @@ public class Workspace extends SmoothPagedView
|
||||
return mChildrenOutlineAlpha;
|
||||
}
|
||||
|
||||
private void animateBackgroundGradient(float finalAlpha, boolean animated) {
|
||||
final DragLayer dragLayer = mLauncher.getDragLayer();
|
||||
|
||||
if (mBackgroundFadeInAnimation != null) {
|
||||
mBackgroundFadeInAnimation.cancel();
|
||||
mBackgroundFadeInAnimation = null;
|
||||
}
|
||||
if (mBackgroundFadeOutAnimation != null) {
|
||||
mBackgroundFadeOutAnimation.cancel();
|
||||
mBackgroundFadeOutAnimation = null;
|
||||
}
|
||||
float startAlpha = dragLayer.getBackgroundAlpha();
|
||||
if (finalAlpha != startAlpha) {
|
||||
if (animated) {
|
||||
mBackgroundFadeOutAnimation =
|
||||
LauncherAnimUtils.ofFloat(this, startAlpha, finalAlpha);
|
||||
mBackgroundFadeOutAnimation.addUpdateListener(new AnimatorUpdateListener() {
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
dragLayer.setBackgroundAlpha(
|
||||
((Float)animation.getAnimatedValue()).floatValue());
|
||||
}
|
||||
});
|
||||
mBackgroundFadeOutAnimation.setInterpolator(new DecelerateInterpolator(1.5f));
|
||||
mBackgroundFadeOutAnimation.setDuration(BACKGROUND_FADE_OUT_DURATION);
|
||||
mBackgroundFadeOutAnimation.start();
|
||||
} else {
|
||||
dragLayer.setBackgroundAlpha(finalAlpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float backgroundAlphaInterpolator(float r) {
|
||||
float pivotA = 0.1f;
|
||||
float pivotB = 0.4f;
|
||||
@@ -1737,7 +1690,7 @@ public class Workspace extends SmoothPagedView
|
||||
OnClickListener listener = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
enterOverviewMode();
|
||||
mLauncher.showOverviewMode(true);
|
||||
}
|
||||
};
|
||||
return listener;
|
||||
@@ -1797,9 +1750,6 @@ public class Workspace extends SmoothPagedView
|
||||
getPageIndicator().setOnClickListener(listener);
|
||||
}
|
||||
}
|
||||
AccessibilityManager am = (AccessibilityManager)
|
||||
getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
|
||||
sAccessibilityEnabled = am.isEnabled();
|
||||
|
||||
// Update wallpaper dimensions if they were changed since last onResume
|
||||
// (we also always set the wallpaper dimensions in the constructor)
|
||||
@@ -1969,64 +1919,6 @@ public class Workspace extends SmoothPagedView
|
||||
position[0], position[1], 0, null);
|
||||
}
|
||||
|
||||
/*
|
||||
* This interpolator emulates the rate at which the perceived scale of an object changes
|
||||
* as its distance from a camera increases. When this interpolator is applied to a scale
|
||||
* animation on a view, it evokes the sense that the object is shrinking due to moving away
|
||||
* from the camera.
|
||||
*/
|
||||
static class ZInterpolator implements TimeInterpolator {
|
||||
private float focalLength;
|
||||
|
||||
public ZInterpolator(float foc) {
|
||||
focalLength = foc;
|
||||
}
|
||||
|
||||
public float getInterpolation(float input) {
|
||||
return (1.0f - focalLength / (focalLength + input)) /
|
||||
(1.0f - focalLength / (focalLength + 1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The exact reverse of ZInterpolator.
|
||||
*/
|
||||
static class InverseZInterpolator implements TimeInterpolator {
|
||||
private ZInterpolator zInterpolator;
|
||||
public InverseZInterpolator(float foc) {
|
||||
zInterpolator = new ZInterpolator(foc);
|
||||
}
|
||||
public float getInterpolation(float input) {
|
||||
return 1 - zInterpolator.getInterpolation(1 - input);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ZInterpolator compounded with an ease-out.
|
||||
*/
|
||||
static class ZoomOutInterpolator implements TimeInterpolator {
|
||||
private final DecelerateInterpolator decelerate = new DecelerateInterpolator(0.75f);
|
||||
private final ZInterpolator zInterpolator = new ZInterpolator(0.13f);
|
||||
|
||||
public float getInterpolation(float input) {
|
||||
return decelerate.getInterpolation(zInterpolator.getInterpolation(input));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* InvereZInterpolator compounded with an ease-out.
|
||||
*/
|
||||
static class ZoomInInterpolator implements TimeInterpolator {
|
||||
private final InverseZInterpolator inverseZInterpolator = new InverseZInterpolator(0.35f);
|
||||
private final DecelerateInterpolator decelerate = new DecelerateInterpolator(3.0f);
|
||||
|
||||
public float getInterpolation(float input) {
|
||||
return decelerate.getInterpolation(inverseZInterpolator.getInterpolation(input));
|
||||
}
|
||||
}
|
||||
|
||||
private final ZoomInInterpolator mZoomInInterpolator = new ZoomInInterpolator();
|
||||
|
||||
/*
|
||||
*
|
||||
* We call these methods (onDragStartedWithItemSpans/onDragStartedWithSize) whenever we
|
||||
@@ -2090,21 +1982,6 @@ public class Workspace extends SmoothPagedView
|
||||
dragLayer.clearAllResizeFrames();
|
||||
}
|
||||
|
||||
private void initAnimationArrays() {
|
||||
final int childCount = getChildCount();
|
||||
if (mLastChildCount == childCount) return;
|
||||
|
||||
mOldBackgroundAlphas = new float[childCount];
|
||||
mOldAlphas = new float[childCount];
|
||||
mNewBackgroundAlphas = new float[childCount];
|
||||
mNewAlphas = new float[childCount];
|
||||
}
|
||||
|
||||
Animator getChangeStateAnimation(final State state, boolean animated,
|
||||
HashMap<View, Integer> layerViews) {
|
||||
return getChangeStateAnimation(state, animated, 0, -1, layerViews);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getFreeScrollPageRange(int[] range) {
|
||||
getOverviewModePages(range);
|
||||
@@ -2151,41 +2028,6 @@ public class Workspace extends SmoothPagedView
|
||||
return mState == State.OVERVIEW;
|
||||
}
|
||||
|
||||
public boolean enterOverviewMode() {
|
||||
if (mTouchState != TOUCH_STATE_REST) {
|
||||
return false;
|
||||
}
|
||||
enableOverviewMode(true, -1, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void exitOverviewMode(boolean animated) {
|
||||
exitOverviewMode(-1, animated);
|
||||
}
|
||||
|
||||
public void exitOverviewMode(int snapPage, boolean animated) {
|
||||
enableOverviewMode(false, snapPage, animated);
|
||||
}
|
||||
|
||||
private void enableOverviewMode(boolean enable, int snapPage, boolean animated) {
|
||||
State finalState = Workspace.State.OVERVIEW;
|
||||
if (!enable) {
|
||||
finalState = Workspace.State.NORMAL;
|
||||
}
|
||||
|
||||
Animator workspaceAnim = getChangeStateAnimation(finalState, animated, 0, snapPage);
|
||||
if (workspaceAnim != null) {
|
||||
onTransitionPrepare();
|
||||
workspaceAnim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator arg0) {
|
||||
onTransitionEnd();
|
||||
}
|
||||
});
|
||||
workspaceAnim.start();
|
||||
}
|
||||
}
|
||||
|
||||
int getOverviewModeTranslationY() {
|
||||
LauncherAppState app = LauncherAppState.getInstance();
|
||||
DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
|
||||
@@ -2208,10 +2050,22 @@ public class Workspace extends SmoothPagedView
|
||||
}
|
||||
}
|
||||
|
||||
private void setState(State state) {
|
||||
mState = state;
|
||||
/**
|
||||
* Sets the current workspace {@link State}, returning an animation transitioning the workspace
|
||||
* to that new state.
|
||||
*/
|
||||
public Animator setStateWithAnimation(State toState, int toPage, boolean animated,
|
||||
HashMap<View, Integer> layerViews) {
|
||||
// Create the animation to the new state
|
||||
Animator workspaceAnim = mStateTransitionAnimation.getAnimationToState(getState(),
|
||||
toState, toPage, animated, layerViews);
|
||||
|
||||
// Update the current state
|
||||
mState = toState;
|
||||
updateInteractionForState();
|
||||
updateAccessibilityFlags();
|
||||
|
||||
return workspaceAnim;
|
||||
}
|
||||
|
||||
State getState() {
|
||||
@@ -2225,321 +2079,15 @@ public class Workspace extends SmoothPagedView
|
||||
setImportantForAccessibility(accessible);
|
||||
}
|
||||
|
||||
private static final int HIDE_WORKSPACE_DURATION = 100;
|
||||
|
||||
Animator getChangeStateAnimation(final State state, boolean animated, int delay, int snapPage) {
|
||||
return getChangeStateAnimation(state, animated, delay, snapPage, null);
|
||||
}
|
||||
|
||||
Animator getChangeStateAnimation(final State state, boolean animated, int delay, int snapPage,
|
||||
HashMap<View, Integer> layerViews) {
|
||||
if (mState == state) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Initialize animation arrays for the first time if necessary
|
||||
initAnimationArrays();
|
||||
|
||||
AnimatorSet anim = animated ? LauncherAnimUtils.createAnimatorSet() : null;
|
||||
|
||||
// We only want a single instance of a workspace animation to be running at once, so
|
||||
// we cancel any incomplete transition.
|
||||
if (mStateAnimator != null) {
|
||||
mStateAnimator.cancel();
|
||||
}
|
||||
mStateAnimator = anim;
|
||||
|
||||
final State oldState = mState;
|
||||
final boolean oldStateIsNormal = (oldState == State.NORMAL);
|
||||
final boolean oldStateIsSpringLoaded = (oldState == State.SPRING_LOADED);
|
||||
final boolean oldStateIsNormalHidden = (oldState == State.NORMAL_HIDDEN);
|
||||
final boolean oldStateIsOverviewHidden = (oldState == State.OVERVIEW_HIDDEN);
|
||||
final boolean oldStateIsOverview = (oldState == State.OVERVIEW);
|
||||
setState(state);
|
||||
final boolean stateIsNormal = (state == State.NORMAL);
|
||||
final boolean stateIsSpringLoaded = (state == State.SPRING_LOADED);
|
||||
final boolean stateIsNormalHidden = (state == State.NORMAL_HIDDEN);
|
||||
final boolean stateIsOverviewHidden = (state == State.OVERVIEW_HIDDEN);
|
||||
final boolean stateIsOverview = (state == State.OVERVIEW);
|
||||
float finalBackgroundAlpha = (stateIsSpringLoaded || stateIsOverview) ? 1.0f : 0f;
|
||||
float finalHotseatAndPageIndicatorAlpha = (stateIsNormal || stateIsSpringLoaded) ? 1f : 0f;
|
||||
float finalOverviewPanelAlpha = stateIsOverview ? 1f : 0f;
|
||||
// We keep the search bar visible on the workspace and in AllApps now
|
||||
boolean showSearchBar = stateIsNormal ||
|
||||
(mLauncher.isAllAppsSearchOverridden() && stateIsNormalHidden);
|
||||
float finalSearchBarAlpha = showSearchBar ? 1f : 0f;
|
||||
float finalWorkspaceTranslationY = stateIsOverview || stateIsOverviewHidden ?
|
||||
getOverviewModeTranslationY() : 0;
|
||||
|
||||
boolean workspaceToAllApps = (oldStateIsNormal && stateIsNormalHidden);
|
||||
boolean overviewToAllApps = (oldStateIsOverview && stateIsOverviewHidden);
|
||||
boolean allAppsToWorkspace = (stateIsNormalHidden && stateIsNormal);
|
||||
boolean workspaceToOverview = (oldStateIsNormal && stateIsOverview);
|
||||
boolean overviewToWorkspace = (oldStateIsOverview && stateIsNormal);
|
||||
|
||||
mNewScale = 1.0f;
|
||||
|
||||
if (oldStateIsOverview) {
|
||||
disableFreeScroll();
|
||||
} else if (stateIsOverview) {
|
||||
enableFreeScroll();
|
||||
}
|
||||
|
||||
if (state != State.NORMAL) {
|
||||
if (stateIsSpringLoaded) {
|
||||
mNewScale = mSpringLoadedShrinkFactor;
|
||||
} else if (stateIsOverview || stateIsOverviewHidden) {
|
||||
mNewScale = mOverviewModeShrinkFactor;
|
||||
}
|
||||
}
|
||||
|
||||
final int duration;
|
||||
if (workspaceToAllApps || overviewToAllApps) {
|
||||
duration = HIDE_WORKSPACE_DURATION; //getResources().getInteger(R.integer.config_workspaceUnshrinkTime);
|
||||
} else if (workspaceToOverview || overviewToWorkspace) {
|
||||
duration = getResources().getInteger(R.integer.config_overviewTransitionTime);
|
||||
} else {
|
||||
duration = getResources().getInteger(R.integer.config_appsCustomizeWorkspaceShrinkTime);
|
||||
}
|
||||
|
||||
if (snapPage == -1) {
|
||||
snapPage = getPageNearestToCenterOfScreen();
|
||||
}
|
||||
snapToPage(snapPage, duration, mZoomInInterpolator);
|
||||
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
final CellLayout cl = (CellLayout) getChildAt(i);
|
||||
boolean isCurrentPage = (i == snapPage);
|
||||
float initialAlpha = cl.getShortcutsAndWidgets().getAlpha();
|
||||
float finalAlpha;
|
||||
if (stateIsNormalHidden || stateIsOverviewHidden) {
|
||||
finalAlpha = 0f;
|
||||
} else if (stateIsNormal && mWorkspaceFadeInAdjacentScreens) {
|
||||
finalAlpha = (i == snapPage || i < numCustomPages()) ? 1f : 0f;
|
||||
} else {
|
||||
finalAlpha = 1f;
|
||||
}
|
||||
|
||||
// If we are animating to/from the small state, then hide the side pages and fade the
|
||||
// current page in
|
||||
if (!mIsSwitchingState) {
|
||||
if (workspaceToAllApps || allAppsToWorkspace) {
|
||||
if (allAppsToWorkspace && isCurrentPage) {
|
||||
initialAlpha = 0f;
|
||||
} else if (!isCurrentPage) {
|
||||
initialAlpha = finalAlpha = 0f;
|
||||
}
|
||||
cl.setShortcutAndWidgetAlpha(initialAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
mOldAlphas[i] = initialAlpha;
|
||||
mNewAlphas[i] = finalAlpha;
|
||||
if (animated) {
|
||||
mOldBackgroundAlphas[i] = cl.getBackgroundAlpha();
|
||||
mNewBackgroundAlphas[i] = finalBackgroundAlpha;
|
||||
} else {
|
||||
cl.setBackgroundAlpha(finalBackgroundAlpha);
|
||||
cl.setShortcutAndWidgetAlpha(finalAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
final View searchBar = mLauncher.getOrCreateQsbBar();
|
||||
final View overviewPanel = mLauncher.getOverviewPanel();
|
||||
final View hotseat = mLauncher.getHotseat();
|
||||
final View pageIndicator = getPageIndicator();
|
||||
if (animated) {
|
||||
LauncherViewPropertyAnimator scale = new LauncherViewPropertyAnimator(this);
|
||||
scale.scaleX(mNewScale)
|
||||
.scaleY(mNewScale)
|
||||
.translationY(finalWorkspaceTranslationY)
|
||||
.setDuration(duration)
|
||||
.setInterpolator(mZoomInInterpolator);
|
||||
anim.play(scale);
|
||||
for (int index = 0; index < getChildCount(); index++) {
|
||||
final int i = index;
|
||||
final CellLayout cl = (CellLayout) getChildAt(i);
|
||||
float currentAlpha = cl.getShortcutsAndWidgets().getAlpha();
|
||||
if (mOldAlphas[i] == 0 && mNewAlphas[i] == 0) {
|
||||
cl.setBackgroundAlpha(mNewBackgroundAlphas[i]);
|
||||
cl.setShortcutAndWidgetAlpha(mNewAlphas[i]);
|
||||
} else {
|
||||
if (layerViews != null) {
|
||||
layerViews.put(cl, LauncherStateTransitionAnimation.BUILD_LAYER);
|
||||
}
|
||||
if (mOldAlphas[i] != mNewAlphas[i] || currentAlpha != mNewAlphas[i]) {
|
||||
LauncherViewPropertyAnimator alphaAnim =
|
||||
new LauncherViewPropertyAnimator(cl.getShortcutsAndWidgets());
|
||||
alphaAnim.alpha(mNewAlphas[i])
|
||||
.setDuration(duration)
|
||||
.setInterpolator(mZoomInInterpolator);
|
||||
anim.play(alphaAnim);
|
||||
}
|
||||
if (mOldBackgroundAlphas[i] != 0 ||
|
||||
mNewBackgroundAlphas[i] != 0) {
|
||||
ValueAnimator bgAnim =
|
||||
LauncherAnimUtils.ofFloat(cl, 0f, 1f);
|
||||
bgAnim.setInterpolator(mZoomInInterpolator);
|
||||
bgAnim.setDuration(duration);
|
||||
bgAnim.addUpdateListener(new LauncherAnimatorUpdateListener() {
|
||||
public void onAnimationUpdate(float a, float b) {
|
||||
cl.setBackgroundAlpha(
|
||||
a * mOldBackgroundAlphas[i] +
|
||||
b * mNewBackgroundAlphas[i]);
|
||||
}
|
||||
});
|
||||
anim.play(bgAnim);
|
||||
}
|
||||
}
|
||||
}
|
||||
Animator pageIndicatorAlpha = null;
|
||||
if (pageIndicator != null) {
|
||||
pageIndicatorAlpha = new LauncherViewPropertyAnimator(pageIndicator)
|
||||
.alpha(finalHotseatAndPageIndicatorAlpha).withLayer();
|
||||
pageIndicatorAlpha.addListener(new AlphaUpdateListener(pageIndicator));
|
||||
} else {
|
||||
// create a dummy animation so we don't need to do null checks later
|
||||
pageIndicatorAlpha = ValueAnimator.ofFloat(0, 0);
|
||||
}
|
||||
|
||||
LauncherViewPropertyAnimator hotseatAlpha = new LauncherViewPropertyAnimator(hotseat)
|
||||
.alpha(finalHotseatAndPageIndicatorAlpha);
|
||||
hotseatAlpha.addListener(new AlphaUpdateListener(hotseat));
|
||||
|
||||
LauncherViewPropertyAnimator overviewPanelAlpha =
|
||||
new LauncherViewPropertyAnimator(overviewPanel).alpha(finalOverviewPanelAlpha);
|
||||
overviewPanelAlpha.addListener(new AlphaUpdateListener(overviewPanel));
|
||||
|
||||
// For animation optimations, we may need to provide the Launcher transition
|
||||
// with a set of views on which to force build layers in certain scenarios.
|
||||
hotseat.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||
overviewPanel.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||
if (layerViews != null) {
|
||||
// If layerViews is not null, we add these views, and indicate that
|
||||
// the caller can manage layer state.
|
||||
layerViews.put(hotseat, LauncherStateTransitionAnimation.BUILD_AND_SET_LAYER);
|
||||
layerViews.put(overviewPanel, LauncherStateTransitionAnimation.BUILD_AND_SET_LAYER);
|
||||
} else {
|
||||
// Otherwise let the animator handle layer management.
|
||||
hotseatAlpha.withLayer();
|
||||
overviewPanelAlpha.withLayer();
|
||||
}
|
||||
|
||||
if (workspaceToOverview) {
|
||||
pageIndicatorAlpha.setInterpolator(new DecelerateInterpolator(2));
|
||||
hotseatAlpha.setInterpolator(new DecelerateInterpolator(2));
|
||||
overviewPanelAlpha.setInterpolator(null);
|
||||
} else if (overviewToWorkspace) {
|
||||
pageIndicatorAlpha.setInterpolator(null);
|
||||
hotseatAlpha.setInterpolator(null);
|
||||
overviewPanelAlpha.setInterpolator(new DecelerateInterpolator(2));
|
||||
}
|
||||
|
||||
overviewPanelAlpha.setDuration(duration);
|
||||
pageIndicatorAlpha.setDuration(duration);
|
||||
hotseatAlpha.setDuration(duration);
|
||||
|
||||
if (searchBar != null) {
|
||||
LauncherViewPropertyAnimator searchBarAlpha = new LauncherViewPropertyAnimator(searchBar)
|
||||
.alpha(finalSearchBarAlpha);
|
||||
searchBarAlpha.addListener(new AlphaUpdateListener(searchBar));
|
||||
searchBar.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||
if (layerViews != null) {
|
||||
// If layerViews is not null, we add these views, and indicate that
|
||||
// the caller can manage layer state.
|
||||
layerViews.put(searchBar, LauncherStateTransitionAnimation.BUILD_AND_SET_LAYER);
|
||||
} else {
|
||||
// Otherwise let the animator handle layer management.
|
||||
searchBarAlpha.withLayer();
|
||||
}
|
||||
searchBarAlpha.setDuration(duration);
|
||||
anim.play(searchBarAlpha);
|
||||
}
|
||||
|
||||
anim.play(overviewPanelAlpha);
|
||||
anim.play(hotseatAlpha);
|
||||
anim.play(pageIndicatorAlpha);
|
||||
anim.setStartDelay(delay);
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mStateAnimator = null;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
overviewPanel.setAlpha(finalOverviewPanelAlpha);
|
||||
AlphaUpdateListener.updateVisibility(overviewPanel);
|
||||
hotseat.setAlpha(finalHotseatAndPageIndicatorAlpha);
|
||||
AlphaUpdateListener.updateVisibility(hotseat);
|
||||
if (pageIndicator != null) {
|
||||
pageIndicator.setAlpha(finalHotseatAndPageIndicatorAlpha);
|
||||
AlphaUpdateListener.updateVisibility(pageIndicator);
|
||||
}
|
||||
if (searchBar != null) {
|
||||
searchBar.setAlpha(finalSearchBarAlpha);
|
||||
AlphaUpdateListener.updateVisibility(searchBar);
|
||||
}
|
||||
updateCustomContentVisibility();
|
||||
setScaleX(mNewScale);
|
||||
setScaleY(mNewScale);
|
||||
setTranslationY(finalWorkspaceTranslationY);
|
||||
}
|
||||
|
||||
if (stateIsNormal) {
|
||||
animateBackgroundGradient(0f, animated);
|
||||
} else {
|
||||
animateBackgroundGradient(getResources().getInteger(
|
||||
R.integer.config_workspaceScrimAlpha) / 100f, animated);
|
||||
}
|
||||
return anim;
|
||||
}
|
||||
|
||||
static class AlphaUpdateListener implements AnimatorUpdateListener, AnimatorListener {
|
||||
View view;
|
||||
public AlphaUpdateListener(View v) {
|
||||
view = v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator arg0) {
|
||||
updateVisibility(view);
|
||||
}
|
||||
|
||||
public static void updateVisibility(View view) {
|
||||
// We want to avoid the extra layout pass by setting the views to GONE unless
|
||||
// accessibility is on, in which case not setting them to GONE causes a glitch.
|
||||
int invisibleState = sAccessibilityEnabled ? GONE : INVISIBLE;
|
||||
if (view.getAlpha() < ALPHA_CUTOFF_THRESHOLD && view.getVisibility() != invisibleState) {
|
||||
view.setVisibility(invisibleState);
|
||||
} else if (view.getAlpha() > ALPHA_CUTOFF_THRESHOLD
|
||||
&& view.getVisibility() != VISIBLE) {
|
||||
view.setVisibility(VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator arg0) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator arg0) {
|
||||
updateVisibility(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator arg0) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationStart(Animator arg0) {
|
||||
// We want the views to be visible for animation, so fade-in/out is visible
|
||||
view.setVisibility(VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace) {
|
||||
onTransitionPrepare();
|
||||
mIsSwitchingState = true;
|
||||
|
||||
// Invalidate here to ensure that the pages are rendered during the state change transition.
|
||||
invalidate();
|
||||
|
||||
updateChildrenLayersEnabled(false);
|
||||
hideCustomContentIfNecessary();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2553,17 +2101,9 @@ public class Workspace extends SmoothPagedView
|
||||
|
||||
@Override
|
||||
public void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace) {
|
||||
onTransitionEnd();
|
||||
}
|
||||
|
||||
private void onTransitionPrepare() {
|
||||
mIsSwitchingState = true;
|
||||
|
||||
// Invalidate here to ensure that the pages are rendered during the state change transition.
|
||||
invalidate();
|
||||
|
||||
mIsSwitchingState = false;
|
||||
updateChildrenLayersEnabled(false);
|
||||
hideCustomContentIfNecessary();
|
||||
showCustomContentIfNecessary();
|
||||
}
|
||||
|
||||
void updateCustomContentVisibility() {
|
||||
@@ -2589,12 +2129,6 @@ public class Workspace extends SmoothPagedView
|
||||
}
|
||||
}
|
||||
|
||||
@Thunk void onTransitionEnd() {
|
||||
mIsSwitchingState = false;
|
||||
updateChildrenLayersEnabled(false);
|
||||
showCustomContentIfNecessary();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getContent() {
|
||||
return this;
|
||||
@@ -3106,7 +2640,7 @@ public class Workspace extends SmoothPagedView
|
||||
}
|
||||
}
|
||||
|
||||
int snapScreen = -1;
|
||||
int snapScreen = WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE;
|
||||
boolean resizeOnDrop = false;
|
||||
if (d.dragSource != this) {
|
||||
final int[] touchXY = new int[] { (int) mDragViewVisualCenter[0],
|
||||
@@ -3267,7 +2801,9 @@ public class Workspace extends SmoothPagedView
|
||||
animateWidgetDrop(info, parent, d.dragView,
|
||||
onCompleteRunnable, animationType, cell, false);
|
||||
} else {
|
||||
int duration = snapScreen < 0 ? -1 : ADJACENT_SCREEN_DROP_DURATION;
|
||||
int duration = snapScreen < 0 ?
|
||||
WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE :
|
||||
ADJACENT_SCREEN_DROP_DURATION;
|
||||
mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, cell, duration,
|
||||
onCompleteRunnable, this);
|
||||
}
|
||||
@@ -4165,8 +3701,8 @@ public class Workspace extends SmoothPagedView
|
||||
public void setFinalTransitionTransform(CellLayout layout) {
|
||||
if (isSwitchingState()) {
|
||||
mCurrentScale = getScaleX();
|
||||
setScaleX(mNewScale);
|
||||
setScaleY(mNewScale);
|
||||
setScaleX(mStateTransitionAnimation.getFinalScale());
|
||||
setScaleY(mStateTransitionAnimation.getFinalScale());
|
||||
}
|
||||
}
|
||||
public void resetTransitionTransform(CellLayout layout) {
|
||||
|
||||
@@ -0,0 +1,519 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* A convenience class to update a view's visibility state after an alpha animation.
|
||||
*/
|
||||
class AlphaUpdateListener extends AnimatorListenerAdapter implements ValueAnimator.AnimatorUpdateListener {
|
||||
private static final float ALPHA_CUTOFF_THRESHOLD = 0.01f;
|
||||
|
||||
private View mView;
|
||||
private boolean mAccessibilityEnabled;
|
||||
|
||||
public AlphaUpdateListener(View v, boolean accessibilityEnabled) {
|
||||
mView = v;
|
||||
mAccessibilityEnabled = accessibilityEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator arg0) {
|
||||
updateVisibility(mView, mAccessibilityEnabled);
|
||||
}
|
||||
|
||||
public static void updateVisibility(View view, boolean accessibilityEnabled) {
|
||||
// We want to avoid the extra layout pass by setting the views to GONE unless
|
||||
// accessibility is on, in which case not setting them to GONE causes a glitch.
|
||||
int invisibleState = accessibilityEnabled ? View.GONE : View.INVISIBLE;
|
||||
if (view.getAlpha() < ALPHA_CUTOFF_THRESHOLD && view.getVisibility() != invisibleState) {
|
||||
view.setVisibility(invisibleState);
|
||||
} else if (view.getAlpha() > ALPHA_CUTOFF_THRESHOLD
|
||||
&& view.getVisibility() != View.VISIBLE) {
|
||||
view.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator arg0) {
|
||||
updateVisibility(mView, mAccessibilityEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationStart(Animator arg0) {
|
||||
// We want the views to be visible for animation, so fade-in/out is visible
|
||||
mView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This interpolator emulates the rate at which the perceived scale of an object changes
|
||||
* as its distance from a camera increases. When this interpolator is applied to a scale
|
||||
* animation on a view, it evokes the sense that the object is shrinking due to moving away
|
||||
* from the camera.
|
||||
*/
|
||||
class ZInterpolator implements TimeInterpolator {
|
||||
private float focalLength;
|
||||
|
||||
public ZInterpolator(float foc) {
|
||||
focalLength = foc;
|
||||
}
|
||||
|
||||
public float getInterpolation(float input) {
|
||||
return (1.0f - focalLength / (focalLength + input)) /
|
||||
(1.0f - focalLength / (focalLength + 1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The exact reverse of ZInterpolator.
|
||||
*/
|
||||
class InverseZInterpolator implements TimeInterpolator {
|
||||
private ZInterpolator zInterpolator;
|
||||
public InverseZInterpolator(float foc) {
|
||||
zInterpolator = new ZInterpolator(foc);
|
||||
}
|
||||
public float getInterpolation(float input) {
|
||||
return 1 - zInterpolator.getInterpolation(1 - input);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* InverseZInterpolator compounded with an ease-out.
|
||||
*/
|
||||
class ZoomInInterpolator implements TimeInterpolator {
|
||||
private final InverseZInterpolator inverseZInterpolator = new InverseZInterpolator(0.35f);
|
||||
private final DecelerateInterpolator decelerate = new DecelerateInterpolator(3.0f);
|
||||
|
||||
public float getInterpolation(float input) {
|
||||
return decelerate.getInterpolation(inverseZInterpolator.getInterpolation(input));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages the animations between each of the workspace states.
|
||||
*/
|
||||
public class WorkspaceStateTransitionAnimation {
|
||||
|
||||
public static final String TAG = "WorkspaceStateTransitionAnimation";
|
||||
|
||||
public static final int SCROLL_TO_CURRENT_PAGE = -1;
|
||||
@Thunk static final int BACKGROUND_FADE_OUT_DURATION = 350;
|
||||
|
||||
final @Thunk Launcher mLauncher;
|
||||
final @Thunk Workspace mWorkspace;
|
||||
|
||||
@Thunk AnimatorSet mStateAnimator;
|
||||
@Thunk float[] mOldBackgroundAlphas;
|
||||
@Thunk float[] mOldAlphas;
|
||||
@Thunk float[] mNewBackgroundAlphas;
|
||||
@Thunk float[] mNewAlphas;
|
||||
@Thunk int mLastChildCount = -1;
|
||||
|
||||
@Thunk float mCurrentScale;
|
||||
@Thunk float mNewScale;
|
||||
|
||||
@Thunk final ZoomInInterpolator mZoomInInterpolator = new ZoomInInterpolator();
|
||||
|
||||
// These properties refer to the background protection gradient used for AllApps and Customize
|
||||
@Thunk ValueAnimator mBackgroundFadeInAnimation;
|
||||
@Thunk ValueAnimator mBackgroundFadeOutAnimation;
|
||||
|
||||
@Thunk float mSpringLoadedShrinkFactor;
|
||||
@Thunk float mOverviewModeShrinkFactor;
|
||||
@Thunk float mWorkspaceScrimAlpha;
|
||||
@Thunk int mAllAppsTransitionTime;
|
||||
@Thunk int mOverviewTransitionTime;
|
||||
@Thunk int mOverlayTransitionTime;
|
||||
@Thunk boolean mWorkspaceFadeInAdjacentScreens;
|
||||
|
||||
public WorkspaceStateTransitionAnimation(Launcher launcher, Workspace workspace) {
|
||||
mLauncher = launcher;
|
||||
mWorkspace = workspace;
|
||||
|
||||
LauncherAppState app = LauncherAppState.getInstance();
|
||||
DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
|
||||
Resources res = launcher.getResources();
|
||||
mAllAppsTransitionTime = res.getInteger(R.integer.config_workspaceUnshrinkTime);
|
||||
mOverviewTransitionTime = res.getInteger(R.integer.config_overviewTransitionTime);
|
||||
mOverlayTransitionTime = res.getInteger(R.integer.config_appsCustomizeWorkspaceShrinkTime);
|
||||
mSpringLoadedShrinkFactor =
|
||||
res.getInteger(R.integer.config_workspaceSpringLoadShrinkPercentage) / 100f;
|
||||
mWorkspaceScrimAlpha = res.getInteger(R.integer.config_workspaceScrimAlpha) / 100f;
|
||||
mOverviewModeShrinkFactor = grid.getOverviewModeScale();
|
||||
mWorkspaceFadeInAdjacentScreens = grid.shouldFadeAdjacentWorkspaceScreens();
|
||||
}
|
||||
|
||||
public AnimatorSet getAnimationToState(Workspace.State fromState, Workspace.State toState,
|
||||
int toPage, boolean animated,
|
||||
HashMap<View, Integer> layerViews) {
|
||||
getAnimation(fromState, toState, toPage, animated, layerViews);
|
||||
return mStateAnimator;
|
||||
}
|
||||
|
||||
public float getFinalScale() {
|
||||
return mNewScale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a transition animation for the workspace.
|
||||
*/
|
||||
private void getAnimation(final Workspace.State fromState, final Workspace.State toState,
|
||||
int toPage, final boolean animated,
|
||||
final HashMap<View, Integer> layerViews) {
|
||||
AccessibilityManager am = (AccessibilityManager)
|
||||
mLauncher.getSystemService(Context.ACCESSIBILITY_SERVICE);
|
||||
boolean accessibilityEnabled = am.isEnabled();
|
||||
|
||||
// Reinitialize animation arrays for the current workspace state
|
||||
reinitializeAnimationArrays();
|
||||
|
||||
// Cancel existing workspace animations and create a new animator set if requested
|
||||
cancelAnimation();
|
||||
if (animated) {
|
||||
mStateAnimator = LauncherAnimUtils.createAnimatorSet();
|
||||
}
|
||||
|
||||
// Update the workspace state
|
||||
final boolean oldStateIsNormal = (fromState == Workspace.State.NORMAL);
|
||||
final boolean oldStateIsSpringLoaded = (fromState == Workspace.State.SPRING_LOADED);
|
||||
final boolean oldStateIsNormalHidden = (fromState == Workspace.State.NORMAL_HIDDEN);
|
||||
final boolean oldStateIsOverviewHidden = (fromState == Workspace.State.OVERVIEW_HIDDEN);
|
||||
final boolean oldStateIsOverview = (fromState == Workspace.State.OVERVIEW);
|
||||
|
||||
final boolean stateIsNormal = (toState == Workspace.State.NORMAL);
|
||||
final boolean stateIsSpringLoaded = (toState == Workspace.State.SPRING_LOADED);
|
||||
final boolean stateIsNormalHidden = (toState == Workspace.State.NORMAL_HIDDEN);
|
||||
final boolean stateIsOverviewHidden = (toState == Workspace.State.OVERVIEW_HIDDEN);
|
||||
final boolean stateIsOverview = (toState == Workspace.State.OVERVIEW);
|
||||
|
||||
final boolean workspaceToAllApps = (oldStateIsNormal && stateIsNormalHidden);
|
||||
final boolean overviewToAllApps = (oldStateIsOverview && stateIsOverviewHidden);
|
||||
final boolean allAppsToWorkspace = (stateIsNormalHidden && stateIsNormal);
|
||||
final boolean workspaceToOverview = (oldStateIsNormal && stateIsOverview);
|
||||
final boolean overviewToWorkspace = (oldStateIsOverview && stateIsNormal);
|
||||
|
||||
float finalBackgroundAlpha = (stateIsSpringLoaded || stateIsOverview) ? 1.0f : 0f;
|
||||
float finalHotseatAndPageIndicatorAlpha = (stateIsNormal || stateIsSpringLoaded) ? 1f : 0f;
|
||||
float finalOverviewPanelAlpha = stateIsOverview ? 1f : 0f;
|
||||
// We keep the search bar visible on the workspace and in AllApps now
|
||||
boolean showSearchBar = stateIsNormal ||
|
||||
(mLauncher.isAllAppsSearchOverridden() && stateIsNormalHidden);
|
||||
float finalSearchBarAlpha = showSearchBar ? 1f : 0f;
|
||||
float finalWorkspaceTranslationY = stateIsOverview || stateIsOverviewHidden ?
|
||||
mWorkspace.getOverviewModeTranslationY() : 0;
|
||||
|
||||
final int childCount = mWorkspace.getChildCount();
|
||||
final int customPageCount = mWorkspace.numCustomPages();
|
||||
|
||||
mNewScale = 1.0f;
|
||||
|
||||
if (oldStateIsOverview) {
|
||||
mWorkspace.disableFreeScroll();
|
||||
} else if (stateIsOverview) {
|
||||
mWorkspace.enableFreeScroll();
|
||||
}
|
||||
|
||||
if (!stateIsNormal) {
|
||||
if (stateIsSpringLoaded) {
|
||||
mNewScale = mSpringLoadedShrinkFactor;
|
||||
} else if (stateIsOverview || stateIsOverviewHidden) {
|
||||
mNewScale = mOverviewModeShrinkFactor;
|
||||
}
|
||||
}
|
||||
|
||||
final int duration;
|
||||
if (workspaceToAllApps || overviewToAllApps) {
|
||||
duration = mAllAppsTransitionTime;
|
||||
} else if (workspaceToOverview || overviewToWorkspace) {
|
||||
duration = mOverviewTransitionTime;
|
||||
} else {
|
||||
duration = mOverlayTransitionTime;
|
||||
}
|
||||
|
||||
if (toPage == SCROLL_TO_CURRENT_PAGE) {
|
||||
toPage = mWorkspace.getPageNearestToCenterOfScreen();
|
||||
}
|
||||
mWorkspace.snapToPage(toPage, duration, mZoomInInterpolator);
|
||||
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
final CellLayout cl = (CellLayout) mWorkspace.getChildAt(i);
|
||||
boolean isCurrentPage = (i == toPage);
|
||||
float initialAlpha = cl.getShortcutsAndWidgets().getAlpha();
|
||||
float finalAlpha;
|
||||
if (stateIsNormalHidden || stateIsOverviewHidden) {
|
||||
finalAlpha = 0f;
|
||||
} else if (stateIsNormal && mWorkspaceFadeInAdjacentScreens) {
|
||||
finalAlpha = (i == toPage || i < customPageCount) ? 1f : 0f;
|
||||
} else {
|
||||
finalAlpha = 1f;
|
||||
}
|
||||
|
||||
// If we are animating to/from the small state, then hide the side pages and fade the
|
||||
// current page in
|
||||
if (!mWorkspace.isSwitchingState()) {
|
||||
if (workspaceToAllApps || allAppsToWorkspace) {
|
||||
if (allAppsToWorkspace && isCurrentPage) {
|
||||
initialAlpha = 0f;
|
||||
} else if (!isCurrentPage) {
|
||||
initialAlpha = finalAlpha = 0f;
|
||||
}
|
||||
cl.setShortcutAndWidgetAlpha(initialAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
mOldAlphas[i] = initialAlpha;
|
||||
mNewAlphas[i] = finalAlpha;
|
||||
if (animated) {
|
||||
mOldBackgroundAlphas[i] = cl.getBackgroundAlpha();
|
||||
mNewBackgroundAlphas[i] = finalBackgroundAlpha;
|
||||
} else {
|
||||
cl.setBackgroundAlpha(finalBackgroundAlpha);
|
||||
cl.setShortcutAndWidgetAlpha(finalAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
final View searchBar = mLauncher.getOrCreateQsbBar();
|
||||
final View overviewPanel = mLauncher.getOverviewPanel();
|
||||
final View hotseat = mLauncher.getHotseat();
|
||||
final View pageIndicator = mWorkspace.getPageIndicator();
|
||||
if (animated) {
|
||||
LauncherViewPropertyAnimator scale = new LauncherViewPropertyAnimator(mWorkspace);
|
||||
scale.scaleX(mNewScale)
|
||||
.scaleY(mNewScale)
|
||||
.translationY(finalWorkspaceTranslationY)
|
||||
.setDuration(duration)
|
||||
.setInterpolator(mZoomInInterpolator);
|
||||
mStateAnimator.play(scale);
|
||||
for (int index = 0; index < childCount; index++) {
|
||||
final int i = index;
|
||||
final CellLayout cl = (CellLayout) mWorkspace.getChildAt(i);
|
||||
float currentAlpha = cl.getShortcutsAndWidgets().getAlpha();
|
||||
if (mOldAlphas[i] == 0 && mNewAlphas[i] == 0) {
|
||||
cl.setBackgroundAlpha(mNewBackgroundAlphas[i]);
|
||||
cl.setShortcutAndWidgetAlpha(mNewAlphas[i]);
|
||||
} else {
|
||||
if (layerViews != null) {
|
||||
layerViews.put(cl, LauncherStateTransitionAnimation.BUILD_LAYER);
|
||||
}
|
||||
if (mOldAlphas[i] != mNewAlphas[i] || currentAlpha != mNewAlphas[i]) {
|
||||
LauncherViewPropertyAnimator alphaAnim =
|
||||
new LauncherViewPropertyAnimator(cl.getShortcutsAndWidgets());
|
||||
alphaAnim.alpha(mNewAlphas[i])
|
||||
.setDuration(duration)
|
||||
.setInterpolator(mZoomInInterpolator);
|
||||
mStateAnimator.play(alphaAnim);
|
||||
}
|
||||
if (mOldBackgroundAlphas[i] != 0 ||
|
||||
mNewBackgroundAlphas[i] != 0) {
|
||||
ValueAnimator bgAnim =
|
||||
LauncherAnimUtils.ofFloat(cl, 0f, 1f);
|
||||
bgAnim.setInterpolator(mZoomInInterpolator);
|
||||
bgAnim.setDuration(duration);
|
||||
bgAnim.addUpdateListener(new LauncherAnimatorUpdateListener() {
|
||||
public void onAnimationUpdate(float a, float b) {
|
||||
cl.setBackgroundAlpha(
|
||||
a * mOldBackgroundAlphas[i] +
|
||||
b * mNewBackgroundAlphas[i]);
|
||||
}
|
||||
});
|
||||
mStateAnimator.play(bgAnim);
|
||||
}
|
||||
}
|
||||
}
|
||||
Animator pageIndicatorAlpha = null;
|
||||
if (pageIndicator != null) {
|
||||
pageIndicatorAlpha = new LauncherViewPropertyAnimator(pageIndicator)
|
||||
.alpha(finalHotseatAndPageIndicatorAlpha).withLayer();
|
||||
pageIndicatorAlpha.addListener(new AlphaUpdateListener(pageIndicator,
|
||||
accessibilityEnabled));
|
||||
} else {
|
||||
// create a dummy animation so we don't need to do null checks later
|
||||
pageIndicatorAlpha = ValueAnimator.ofFloat(0, 0);
|
||||
}
|
||||
|
||||
LauncherViewPropertyAnimator hotseatAlpha = new LauncherViewPropertyAnimator(hotseat)
|
||||
.alpha(finalHotseatAndPageIndicatorAlpha);
|
||||
hotseatAlpha.addListener(new AlphaUpdateListener(hotseat, accessibilityEnabled));
|
||||
|
||||
LauncherViewPropertyAnimator overviewPanelAlpha =
|
||||
new LauncherViewPropertyAnimator(overviewPanel).alpha(finalOverviewPanelAlpha);
|
||||
overviewPanelAlpha.addListener(new AlphaUpdateListener(overviewPanel,
|
||||
accessibilityEnabled));
|
||||
|
||||
// For animation optimations, we may need to provide the Launcher transition
|
||||
// with a set of views on which to force build layers in certain scenarios.
|
||||
hotseat.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||
overviewPanel.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||
if (layerViews != null) {
|
||||
// If layerViews is not null, we add these views, and indicate that
|
||||
// the caller can manage layer state.
|
||||
layerViews.put(hotseat, LauncherStateTransitionAnimation.BUILD_AND_SET_LAYER);
|
||||
layerViews.put(overviewPanel, LauncherStateTransitionAnimation.BUILD_AND_SET_LAYER);
|
||||
} else {
|
||||
// Otherwise let the animator handle layer management.
|
||||
hotseatAlpha.withLayer();
|
||||
overviewPanelAlpha.withLayer();
|
||||
}
|
||||
|
||||
if (workspaceToOverview) {
|
||||
pageIndicatorAlpha.setInterpolator(new DecelerateInterpolator(2));
|
||||
hotseatAlpha.setInterpolator(new DecelerateInterpolator(2));
|
||||
overviewPanelAlpha.setInterpolator(null);
|
||||
} else if (overviewToWorkspace) {
|
||||
pageIndicatorAlpha.setInterpolator(null);
|
||||
hotseatAlpha.setInterpolator(null);
|
||||
overviewPanelAlpha.setInterpolator(new DecelerateInterpolator(2));
|
||||
}
|
||||
|
||||
overviewPanelAlpha.setDuration(duration);
|
||||
pageIndicatorAlpha.setDuration(duration);
|
||||
hotseatAlpha.setDuration(duration);
|
||||
|
||||
// TODO: This should really be coordinated with the SearchDropTargetBar, otherwise the
|
||||
// bar has no idea that it is hidden, and this has no idea what state the bar is
|
||||
// actually in.
|
||||
if (searchBar != null) {
|
||||
LauncherViewPropertyAnimator searchBarAlpha = new LauncherViewPropertyAnimator(searchBar)
|
||||
.alpha(finalSearchBarAlpha);
|
||||
searchBarAlpha.addListener(new AlphaUpdateListener(searchBar, accessibilityEnabled));
|
||||
searchBar.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||
if (layerViews != null) {
|
||||
// If layerViews is not null, we add these views, and indicate that
|
||||
// the caller can manage layer state.
|
||||
layerViews.put(searchBar, LauncherStateTransitionAnimation.BUILD_AND_SET_LAYER);
|
||||
} else {
|
||||
// Otherwise let the animator handle layer management.
|
||||
searchBarAlpha.withLayer();
|
||||
}
|
||||
searchBarAlpha.setDuration(duration);
|
||||
mStateAnimator.play(searchBarAlpha);
|
||||
}
|
||||
|
||||
mStateAnimator.play(overviewPanelAlpha);
|
||||
mStateAnimator.play(hotseatAlpha);
|
||||
mStateAnimator.play(pageIndicatorAlpha);
|
||||
mStateAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mStateAnimator = null;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
overviewPanel.setAlpha(finalOverviewPanelAlpha);
|
||||
AlphaUpdateListener.updateVisibility(overviewPanel, accessibilityEnabled);
|
||||
hotseat.setAlpha(finalHotseatAndPageIndicatorAlpha);
|
||||
AlphaUpdateListener.updateVisibility(hotseat, accessibilityEnabled);
|
||||
if (pageIndicator != null) {
|
||||
pageIndicator.setAlpha(finalHotseatAndPageIndicatorAlpha);
|
||||
AlphaUpdateListener.updateVisibility(pageIndicator, accessibilityEnabled);
|
||||
}
|
||||
if (searchBar != null) {
|
||||
searchBar.setAlpha(finalSearchBarAlpha);
|
||||
AlphaUpdateListener.updateVisibility(searchBar, accessibilityEnabled);
|
||||
}
|
||||
mWorkspace.updateCustomContentVisibility();
|
||||
mWorkspace.setScaleX(mNewScale);
|
||||
mWorkspace.setScaleY(mNewScale);
|
||||
mWorkspace.setTranslationY(finalWorkspaceTranslationY);
|
||||
}
|
||||
|
||||
if (stateIsNormal) {
|
||||
animateBackgroundGradient(0f, animated);
|
||||
} else {
|
||||
animateBackgroundGradient(mWorkspaceScrimAlpha, animated);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitializes the arrays that we need for the animations on each page.
|
||||
*/
|
||||
private void reinitializeAnimationArrays() {
|
||||
final int childCount = mWorkspace.getChildCount();
|
||||
if (mLastChildCount == childCount) return;
|
||||
|
||||
mOldBackgroundAlphas = new float[childCount];
|
||||
mOldAlphas = new float[childCount];
|
||||
mNewBackgroundAlphas = new float[childCount];
|
||||
mNewAlphas = new float[childCount];
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates the background scrim.
|
||||
* TODO(winsonc): Is there a better place for this?
|
||||
*
|
||||
* @param finalAlpha the final alpha for the background scrim
|
||||
* @param animated whether or not to set the background alpha immediately
|
||||
*/
|
||||
private void animateBackgroundGradient(float finalAlpha, boolean animated) {
|
||||
// Cancel any running background animations
|
||||
cancelAnimator(mBackgroundFadeInAnimation);
|
||||
cancelAnimator(mBackgroundFadeOutAnimation);
|
||||
|
||||
final DragLayer dragLayer = mLauncher.getDragLayer();
|
||||
final float startAlpha = dragLayer.getBackgroundAlpha();
|
||||
if (finalAlpha != startAlpha) {
|
||||
if (animated) {
|
||||
mBackgroundFadeOutAnimation =
|
||||
LauncherAnimUtils.ofFloat(mWorkspace, startAlpha, finalAlpha);
|
||||
mBackgroundFadeOutAnimation.addUpdateListener(
|
||||
new ValueAnimator.AnimatorUpdateListener() {
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
dragLayer.setBackgroundAlpha(
|
||||
((Float)animation.getAnimatedValue()).floatValue());
|
||||
}
|
||||
});
|
||||
mBackgroundFadeOutAnimation.setInterpolator(new DecelerateInterpolator(1.5f));
|
||||
mBackgroundFadeOutAnimation.setDuration(BACKGROUND_FADE_OUT_DURATION);
|
||||
mBackgroundFadeOutAnimation.start();
|
||||
} else {
|
||||
dragLayer.setBackgroundAlpha(finalAlpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the current animation.
|
||||
*/
|
||||
private void cancelAnimation() {
|
||||
cancelAnimator(mStateAnimator);
|
||||
mStateAnimator = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the specified animation.
|
||||
*/
|
||||
private void cancelAnimator(Animator animator) {
|
||||
if (animator != null) {
|
||||
animator.setDuration(0);
|
||||
animator.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user