From 6c5891a9fce95eee3d87823d11d21889743e9c68 Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Wed, 9 Jul 2014 23:53:15 -0700 Subject: Preliminary work on Material Transitions -> Early exploration of AllApps Hero transition with circular reveal -> Stripping a bunch of dead code from AppsCustomizeTabHost -> Moved background scrim to DragLayer -> Removed "SMALL" state from workspace: replaced with NORMAL_HIDDEN and OVERVIEW_HIDDEN. This is mainly to reduce the overall usage of the z-space model between allapps/widgets and workspace. There are vestigial remains of this model, mainly due to the overview mode, and a bit for spring-loaded. Change-Id: If2302a24394f0ec66621f01ffa2fc4934aa10c3f --- .../android/launcher3/AppsCustomizePagedView.java | 11 +- .../android/launcher3/AppsCustomizeTabHost.java | 346 ++++----------------- src/com/android/launcher3/DragLayer.java | 30 +- src/com/android/launcher3/FolderIcon.java | 2 +- src/com/android/launcher3/Hotseat.java | 2 +- src/com/android/launcher3/Launcher.java | 342 +++++++++++++++----- .../launcher3/LogAccelerateInterpolator.java | 25 ++ .../launcher3/LogDecelerateInterpolator.java | 26 ++ src/com/android/launcher3/Workspace.java | 145 ++++----- 9 files changed, 458 insertions(+), 471 deletions(-) create mode 100644 src/com/android/launcher3/LogAccelerateInterpolator.java create mode 100644 src/com/android/launcher3/LogDecelerateInterpolator.java (limited to 'src/com/android') diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java index 2520b8a12..0e9969697 100644 --- a/src/com/android/launcher3/AppsCustomizePagedView.java +++ b/src/com/android/launcher3/AppsCustomizePagedView.java @@ -377,8 +377,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen int heightSpec = MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.AT_MOST); mWidgetSpacingLayout.measure(widthSpec, heightSpec); - AppsCustomizeTabHost host = (AppsCustomizeTabHost) getTabHost(); - final boolean hostIsTransitioning = host.isTransitioning(); + final boolean hostIsTransitioning = getTabHost().isInTransition(); // Restore the page int page = getPageForComponent(mSaveInstanceStateItemIndex); @@ -1617,12 +1616,8 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen // If we have reset, then we should not continue to restore the previous state mSaveInstanceStateItemIndex = -1; - AppsCustomizeTabHost tabHost = getTabHost(); - String tag = tabHost.getCurrentTabTag(); - if (tag != null) { - if (!tag.equals(tabHost.getTabTagForContentType(ContentType.Applications))) { - tabHost.setCurrentTabFromContent(ContentType.Applications); - } + if (mContentType != ContentType.Applications) { + setContentType(ContentType.Applications); } if (mCurrentPage != 0) { diff --git a/src/com/android/launcher3/AppsCustomizeTabHost.java b/src/com/android/launcher3/AppsCustomizeTabHost.java index c6455c2fe..334d8b6f6 100644 --- a/src/com/android/launcher3/AppsCustomizeTabHost.java +++ b/src/com/android/launcher3/AppsCustomizeTabHost.java @@ -38,35 +38,20 @@ import android.widget.TextView; import java.util.ArrayList; -public class AppsCustomizeTabHost extends TabHost implements LauncherTransitionable, - TabHost.OnTabChangeListener, Insettable { +public class AppsCustomizeTabHost extends FrameLayout implements LauncherTransitionable, Insettable { static final String LOG_TAG = "AppsCustomizeTabHost"; private static final String APPS_TAB_TAG = "APPS"; private static final String WIDGETS_TAB_TAG = "WIDGETS"; - private final LayoutInflater mLayoutInflater; - private ViewGroup mTabs; - private ViewGroup mTabsContainer; - private AppsCustomizePagedView mAppsCustomizePane; - private FrameLayout mAnimationBuffer; - private LinearLayout mContent; - - private boolean mInTransition; - private boolean mTransitioningToWorkspace; - private boolean mResetAfterTransition; - private Runnable mRelayoutAndMakeVisible; + private AppsCustomizePagedView mPagedView; + private View mContent; + private boolean mInTransition = false; + private final Rect mInsets = new Rect(); public AppsCustomizeTabHost(Context context, AttributeSet attrs) { super(context, attrs); - mLayoutInflater = LayoutInflater.from(context); - mRelayoutAndMakeVisible = new Runnable() { - public void run() { - mTabs.requestLayout(); - mTabsContainer.setAlpha(1f); - } - }; } /** @@ -76,17 +61,17 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona * tabs manually). */ void setContentTypeImmediate(AppsCustomizePagedView.ContentType type) { - setOnTabChangedListener(null); - onTabChangedStart(); - onTabChangedEnd(type); - setCurrentTabByTag(getTabTagForContentType(type)); - setOnTabChangedListener(this); + mPagedView.setContentType(type); + } + + public void setCurrentTabFromContent(AppsCustomizePagedView.ContentType type) { + setContentTypeImmediate(type); } @Override public void setInsets(Rect insets) { mInsets.set(insets); - FrameLayout.LayoutParams flp = (LayoutParams) mContent.getLayoutParams(); + LayoutParams flp = (LayoutParams) mContent.getLayoutParams(); flp.topMargin = insets.top; flp.bottomMargin = insets.bottom; flp.leftMargin = insets.left; @@ -99,212 +84,12 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona */ @Override protected void onFinishInflate() { - // Setup the tab host - setup(); - - final ViewGroup tabsContainer = (ViewGroup) findViewById(R.id.tabs_container); - final TabWidget tabs = getTabWidget(); - final AppsCustomizePagedView appsCustomizePane = (AppsCustomizePagedView) - findViewById(R.id.apps_customize_pane_content); - mTabs = tabs; - mTabsContainer = tabsContainer; - mAppsCustomizePane = appsCustomizePane; - mAnimationBuffer = (FrameLayout) findViewById(R.id.animation_buffer); - mContent = (LinearLayout) findViewById(R.id.apps_customize_content); - if (tabs == null || mAppsCustomizePane == null) throw new Resources.NotFoundException(); - - // Configure the tabs content factory to return the same paged view (that we change the - // content filter on) - TabContentFactory contentFactory = new TabContentFactory() { - public View createTabContent(String tag) { - return appsCustomizePane; - } - }; - - // Create the tabs - TextView tabView; - String label; - label = getContext().getString(R.string.all_apps_button_label); - tabView = (TextView) mLayoutInflater.inflate(R.layout.tab_widget_indicator, tabs, false); - tabView.setText(label); - tabView.setContentDescription(label); - addTab(newTabSpec(APPS_TAB_TAG).setIndicator(tabView).setContent(contentFactory)); - label = getContext().getString(R.string.widgets_tab_label); - tabView = (TextView) mLayoutInflater.inflate(R.layout.tab_widget_indicator, tabs, false); - tabView.setText(label); - tabView.setContentDescription(label); - addTab(newTabSpec(WIDGETS_TAB_TAG).setIndicator(tabView).setContent(contentFactory)); - setOnTabChangedListener(this); - - // Setup the key listener to jump between the last tab view and the market icon - AppsCustomizeTabKeyEventListener keyListener = new AppsCustomizeTabKeyEventListener(); - View lastTab = tabs.getChildTabViewAt(tabs.getTabCount() - 1); - lastTab.setOnKeyListener(keyListener); - View shopButton = findViewById(R.id.market_button); - shopButton.setOnKeyListener(keyListener); - - // Hide the tab bar until we measure - mTabsContainer.setAlpha(0f); + mPagedView = (AppsCustomizePagedView) findViewById(R.id.apps_customize_pane_content); + mContent = findViewById(R.id.content); } - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - boolean remeasureTabWidth = (mTabs.getLayoutParams().width <= 0); - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - // Set the width of the tab list to the content width - if (remeasureTabWidth) { - int contentWidth = mAppsCustomizePane.getPageContentWidth(); - if (contentWidth > 0 && mTabs.getLayoutParams().width != contentWidth) { - // Set the width and show the tab bar - mTabs.getLayoutParams().width = contentWidth; - mRelayoutAndMakeVisible.run(); - } - - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - } - - public boolean onInterceptTouchEvent(MotionEvent ev) { - // If we are mid transitioning to the workspace, then intercept touch events here so we - // can ignore them, otherwise we just let all apps handle the touch events. - if (mInTransition && mTransitioningToWorkspace) { - return true; - } - return super.onInterceptTouchEvent(ev); - }; - - @Override - public boolean onTouchEvent(MotionEvent event) { - // Allow touch events to fall through to the workspace if we are transitioning there - if (mInTransition && mTransitioningToWorkspace) { - return super.onTouchEvent(event); - } - - // Intercept all touch events up to the bottom of the AppsCustomizePane so they do not fall - // through to the workspace and trigger showWorkspace() - if (event.getY() < mAppsCustomizePane.getBottom()) { - return true; - } - return super.onTouchEvent(event); - } - - private void onTabChangedStart() { - } - - private void reloadCurrentPage() { - mAppsCustomizePane.loadAssociatedPages(mAppsCustomizePane.getCurrentPage()); - mAppsCustomizePane.requestFocus(); - } - - private void onTabChangedEnd(AppsCustomizePagedView.ContentType type) { - int bgAlpha = (int) (255 * (getResources().getInteger( - R.integer.config_appsCustomizeSpringLoadedBgAlpha) / 100f)); - setBackgroundColor(Color.argb(bgAlpha, 0, 0, 0)); - mAppsCustomizePane.setContentType(type); - } - - @Override - public void onTabChanged(String tabId) { - final AppsCustomizePagedView.ContentType type = getContentTypeForTabTag(tabId); - - // Animate the changing of the tab content by fading pages in and out - final Resources res = getResources(); - final int duration = res.getInteger(R.integer.config_tabTransitionDuration); - - // We post a runnable here because there is a delay while the first page is loading and - // the feedback from having changed the tab almost feels better than having it stick - post(new Runnable() { - @Override - public void run() { - if (mAppsCustomizePane.getMeasuredWidth() <= 0 || - mAppsCustomizePane.getMeasuredHeight() <= 0) { - reloadCurrentPage(); - return; - } - - // Take the visible pages and re-parent them temporarily to mAnimatorBuffer - // and then cross fade to the new pages - int[] visiblePageRange = new int[2]; - mAppsCustomizePane.getVisiblePages(visiblePageRange); - if (visiblePageRange[0] == -1 && visiblePageRange[1] == -1) { - // If we can't get the visible page ranges, then just skip the animation - reloadCurrentPage(); - return; - } - ArrayList visiblePages = new ArrayList(); - for (int i = visiblePageRange[0]; i <= visiblePageRange[1]; i++) { - visiblePages.add(mAppsCustomizePane.getPageAt(i)); - } - - // We want the pages to be rendered in exactly the same way as they were when - // their parent was mAppsCustomizePane -- so set the scroll on mAnimationBuffer - // to be exactly the same as mAppsCustomizePane, and below, set the left/top - // parameters to be correct for each of the pages - mAnimationBuffer.scrollTo(mAppsCustomizePane.getScrollX(), 0); - - // mAppsCustomizePane renders its children in reverse order, so - // add the pages to mAnimationBuffer in reverse order to match that behavior - for (int i = visiblePages.size() - 1; i >= 0; i--) { - View child = visiblePages.get(i); - if (child instanceof AppsCustomizeCellLayout) { - ((AppsCustomizeCellLayout) child).resetChildrenOnKeyListeners(); - } else if (child instanceof PagedViewGridLayout) { - ((PagedViewGridLayout) child).resetChildrenOnKeyListeners(); - } - PagedViewWidget.setDeletePreviewsWhenDetachedFromWindow(false); - mAppsCustomizePane.removeView(child); - PagedViewWidget.setDeletePreviewsWhenDetachedFromWindow(true); - mAnimationBuffer.setAlpha(1f); - mAnimationBuffer.setVisibility(View.VISIBLE); - LayoutParams p = new FrameLayout.LayoutParams(child.getMeasuredWidth(), - child.getMeasuredHeight()); - p.setMargins((int) child.getLeft(), (int) child.getTop(), 0, 0); - mAnimationBuffer.addView(child, p); - } - - // Toggle the new content - onTabChangedStart(); - onTabChangedEnd(type); - - // Animate the transition - ObjectAnimator outAnim = LauncherAnimUtils.ofFloat(mAnimationBuffer, "alpha", 0f); - outAnim.addListener(new AnimatorListenerAdapter() { - private void clearAnimationBuffer() { - mAnimationBuffer.setVisibility(View.GONE); - PagedViewWidget.setRecyclePreviewsWhenDetachedFromWindow(false); - mAnimationBuffer.removeAllViews(); - PagedViewWidget.setRecyclePreviewsWhenDetachedFromWindow(true); - } - @Override - public void onAnimationEnd(Animator animation) { - clearAnimationBuffer(); - } - @Override - public void onAnimationCancel(Animator animation) { - clearAnimationBuffer(); - } - }); - ObjectAnimator inAnim = LauncherAnimUtils.ofFloat(mAppsCustomizePane, "alpha", 1f); - inAnim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - reloadCurrentPage(); - } - }); - - final AnimatorSet animSet = LauncherAnimUtils.createAnimatorSet(); - animSet.playTogether(outAnim, inAnim); - animSet.setDuration(duration); - animSet.start(); - } - }); - } - - public void setCurrentTabFromContent(AppsCustomizePagedView.ContentType type) { - setOnTabChangedListener(null); - setCurrentTabByTag(getTabTagForContentType(type)); - setOnTabChangedListener(this); + public String getContentTag() { + return getTabTagForContentType(mPagedView.getContentType()); } /** @@ -343,44 +128,41 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona } void reset() { - if (mInTransition) { - // Defer to after the transition to reset - mResetAfterTransition = true; - } else { - // Reset immediately - mAppsCustomizePane.reset(); - } + // Reset immediately + mPagedView.reset(); } - private void enableAndBuildHardwareLayer() { - // isHardwareAccelerated() checks if we're attached to a window and if that - // window is HW accelerated-- we were sometimes not attached to a window - // and buildLayer was throwing an IllegalStateException - if (isHardwareAccelerated()) { - // Turn on hardware layers for performance - setLayerType(LAYER_TYPE_HARDWARE, null); - - // force building the layer, so you don't get a blip early in an animation - // when the layer is created layer - buildLayer(); + public void onWindowVisible() { + if (getVisibility() == VISIBLE) { + mContent.setVisibility(VISIBLE); + // We unload the widget previews when the UI is hidden, so need to reload pages + // Load the current page synchronously, and the neighboring pages asynchronously + mPagedView.loadAssociatedPages(mPagedView.getCurrentPage(), true); + mPagedView.loadAssociatedPages(mPagedView.getCurrentPage()); } } + public void onTrimMemory() { + mContent.setVisibility(GONE); + // Clear the widget pages of all their subviews - this will trigger the widget previews + // to delete their bitmaps + mPagedView.clearAllWidgetPages(); + } + @Override public View getContent() { - View appsCustomizeContent = mAppsCustomizePane.getContent(); - if (appsCustomizeContent != null) { - return appsCustomizeContent; - } - return mContent; + return mPagedView; + } + + public boolean isInTransition() { + return mInTransition; } /* LauncherTransitionable overrides */ @Override public void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace) { - mAppsCustomizePane.onLauncherTransitionPrepare(l, animated, toWorkspace); + mPagedView.onLauncherTransitionPrepare(l, animated, toWorkspace); mInTransition = true; - mTransitioningToWorkspace = toWorkspace; if (toWorkspace) { // Going from All Apps -> Workspace @@ -391,52 +173,43 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona // Make sure the current page is loaded (we start loading the side pages after the // transition to prevent slowing down the animation) - mAppsCustomizePane.loadAssociatedPages(mAppsCustomizePane.getCurrentPage(), true); - } - - if (mResetAfterTransition) { - mAppsCustomizePane.reset(); - mResetAfterTransition = false; + // TODO: revisit this + mPagedView.loadAssociatedPages(mPagedView.getCurrentPage(), true); } } @Override public void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace) { - mAppsCustomizePane.onLauncherTransitionStart(l, animated, toWorkspace); - if (animated) { + mPagedView.onLauncherTransitionStart(l, animated, toWorkspace); + if (animated && !Utilities.isLmp()) { enableAndBuildHardwareLayer(); } - - // Dismiss the workspace cling - l.getLauncherClings().dismissWorkspaceCling(null); } @Override public void onLauncherTransitionStep(Launcher l, float t) { - mAppsCustomizePane.onLauncherTransitionStep(l, t); + mPagedView.onLauncherTransitionStep(l, t); } @Override public void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace) { - mAppsCustomizePane.onLauncherTransitionEnd(l, animated, toWorkspace); + mPagedView.onLauncherTransitionEnd(l, animated, toWorkspace); mInTransition = false; - if (animated) { + if (animated && !Utilities.isLmp()) { setLayerType(LAYER_TYPE_NONE, null); } if (!toWorkspace) { - // Show the all apps cling (if not already shown) - mAppsCustomizePane.showAllAppsCling(); // Make sure adjacent pages are loaded (we wait until after the transition to // prevent slowing down the animation) - mAppsCustomizePane.loadAssociatedPages(mAppsCustomizePane.getCurrentPage()); + mPagedView.loadAssociatedPages(mPagedView.getCurrentPage()); // Opening apps, need to announce what page we are on. AccessibilityManager am = (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); if (am.isEnabled()) { // Notify the user when the page changes - announceForAccessibility(mAppsCustomizePane.getCurrentPageDescription()); + announceForAccessibility(mPagedView.getCurrentPageDescription()); } // Going from Workspace -> All Apps @@ -469,24 +242,19 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona } } - public void onWindowVisible() { - if (getVisibility() == VISIBLE) { - mContent.setVisibility(VISIBLE); - // We unload the widget previews when the UI is hidden, so need to reload pages - // Load the current page synchronously, and the neighboring pages asynchronously - mAppsCustomizePane.loadAssociatedPages(mAppsCustomizePane.getCurrentPage(), true); - mAppsCustomizePane.loadAssociatedPages(mAppsCustomizePane.getCurrentPage()); + private void enableAndBuildHardwareLayer() { + // isHardwareAccelerated() checks if we're attached to a window and if that + // window is HW accelerated-- we were sometimes not attached to a window + // and buildLayer was throwing an IllegalStateException + if (isHardwareAccelerated()) { + // Turn on hardware layers for performance + setLayerType(LAYER_TYPE_HARDWARE, null); + + // force building the layer, so you don't get a blip early in an animation + // when the layer is created layer + buildLayer(); } } - public void onTrimMemory() { - mContent.setVisibility(GONE); - // Clear the widget pages of all their subviews - this will trigger the widget previews - // to delete their bitmaps - mAppsCustomizePane.clearAllWidgetPages(); - } - boolean isTransitioning() { - return mInTransition; - } } diff --git a/src/com/android/launcher3/DragLayer.java b/src/com/android/launcher3/DragLayer.java index c54db0127..8bcc407d6 100644 --- a/src/com/android/launcher3/DragLayer.java +++ b/src/com/android/launcher3/DragLayer.java @@ -77,6 +77,10 @@ public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChang private int mTopViewIndex; private int mChildCountOnLastUpdate = -1; + // Darkening scrim + private Drawable mBackground; + private float mBackgroundAlpha = 0; + /** * Used to create a new DragLayer from XML. * @@ -91,8 +95,10 @@ public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChang setChildrenDrawingOrderEnabled(true); setOnHierarchyChangeListener(this); - mLeftHoverDrawable = getResources().getDrawable(R.drawable.page_hover_left_holo); - mRightHoverDrawable = getResources().getDrawable(R.drawable.page_hover_right_holo); + final Resources res = getResources(); + mLeftHoverDrawable = res.getDrawable(R.drawable.page_hover_left_holo); + mRightHoverDrawable = res.getDrawable(R.drawable.page_hover_right_holo); + mBackground = res.getDrawable(R.drawable.apps_customize_bg); } public void setup(Launcher launcher, DragController controller) { @@ -862,8 +868,17 @@ public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChang @Override protected void dispatchDraw(Canvas canvas) { + // Draw the background gradient below children. + if (mBackground != null && mBackgroundAlpha > 0.0f) { + int alpha = (int) (mBackgroundAlpha * 255); + mBackground.setAlpha(alpha); + mBackground.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); + mBackground.draw(canvas); + } + super.dispatchDraw(canvas); + // Draw screen hover indicators above children. if (mInScrollArea && !LauncherAppState.getInstance().isScreenLarge()) { Workspace workspace = mLauncher.getWorkspace(); int width = getMeasuredWidth(); @@ -887,6 +902,17 @@ public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChang } } + public void setBackgroundAlpha(float alpha) { + if (alpha != mBackgroundAlpha) { + mBackgroundAlpha = alpha; + invalidate(); + } + } + + public float getBackgroundAlpha() { + return mBackgroundAlpha; + } + public void setTouchCompleteListener(TouchCompleteListener listener) { mTouchCompleteListener = listener; } diff --git a/src/com/android/launcher3/FolderIcon.java b/src/com/android/launcher3/FolderIcon.java index 4f674f55a..1adf3e5bb 100644 --- a/src/com/android/launcher3/FolderIcon.java +++ b/src/com/android/launcher3/FolderIcon.java @@ -133,7 +133,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { final ViewGroup cellLayoutChildren = (ViewGroup) getParent(); final ViewGroup cellLayout = (ViewGroup) cellLayoutChildren.getParent(); final Workspace workspace = (Workspace) cellLayout.getParent(); - return !workspace.isSmall(); + return !workspace.workspaceInModalState(); } static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group, diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java index 2d171238f..9934f6665 100644 --- a/src/com/android/launcher3/Hotseat.java +++ b/src/com/android/launcher3/Hotseat.java @@ -175,7 +175,7 @@ public class Hotseat extends FrameLayout { public boolean onInterceptTouchEvent(MotionEvent ev) { // We don't want any clicks to go through to the hotseat unless the workspace is in // the normal state. - if (mLauncher.getWorkspace().isSmall()) { + if (mLauncher.getWorkspace().workspaceInModalState()) { return true; } return false; diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 951b5d459..9ad3917fa 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -82,6 +82,7 @@ import android.view.Menu; import android.view.MotionEvent; import android.view.Surface; import android.view.View; +import android.view.ViewAnimationUtils; import android.view.Window; import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; @@ -91,19 +92,23 @@ import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; import android.view.animation.AccelerateDecelerateInterpolator; +import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; +import android.view.animation.LinearInterpolator; import android.view.inputmethod.InputMethodManager; import android.widget.Advanceable; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; + import com.android.launcher3.compat.LauncherActivityInfoCompat; import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.compat.UserHandleCompat; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.DropTarget.DragObject; import com.android.launcher3.PagedView.PageSwitchListener; + import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; @@ -198,7 +203,6 @@ public class Launcher extends Activity // Type: int[] private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids"; - static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed"; static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed"; @@ -3146,6 +3150,7 @@ public class Launcher extends Activity AppsCustomizePagedView.ContentType contentType = mAppsCustomizeContent.getContentType(); showAppsCustomizeHelper(animated, springLoaded, contentType); } + private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded, final AppsCustomizePagedView.ContentType contentType) { if (mStateAnimation != null) { @@ -3153,10 +3158,15 @@ public class Launcher extends Activity mStateAnimation.cancel(); mStateAnimation = null; } + + boolean material = Utilities.isLmp(); + final Resources res = getResources(); final int duration = res.getInteger(R.integer.config_appsCustomizeZoomInTime); final int fadeDuration = res.getInteger(R.integer.config_appsCustomizeFadeInTime); + final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime); + final float scale = (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor); final View fromView = mWorkspace; final AppsCustomizeTabHost toView = mAppsCustomizeTabHost; @@ -3165,9 +3175,10 @@ public class Launcher extends Activity setPivotsForZoom(toView, scale); - // Shrink workspaces away if going to AppsCustomize from workspace + Workspace.State workspaceState = contentType == AppsCustomizePagedView.ContentType.Widgets ? + Workspace.State.OVERVIEW_HIDDEN : Workspace.State.NORMAL_HIDDEN; Animator workspaceAnim = - mWorkspace.getChangeStateAnimation(Workspace.State.SMALL, animated); + mWorkspace.getChangeStateAnimation(workspaceState, animated); if (!LauncherAppState.isDisableAllApps() || contentType == AppsCustomizePagedView.ContentType.Widgets) { // Set the content type for the all apps/widgets space @@ -3175,65 +3186,151 @@ public class Launcher extends Activity } if (animated) { - toView.setScaleX(scale); - toView.setScaleY(scale); - final LauncherViewPropertyAnimator scaleAnim = new LauncherViewPropertyAnimator(toView); - scaleAnim. - scaleX(1f).scaleY(1f). - setDuration(duration). - setInterpolator(new Workspace.ZoomOutInterpolator()); + if (!material) { + toView.setScaleX(scale); + toView.setScaleY(scale); + final LauncherViewPropertyAnimator scaleAnim = + new LauncherViewPropertyAnimator(toView); + scaleAnim. + scaleX(1f).scaleY(1f). + setDuration(duration). + setInterpolator(new Workspace.ZoomOutInterpolator()); + + toView.setVisibility(View.VISIBLE); + toView.setAlpha(0f); + final ObjectAnimator alphaAnim = LauncherAnimUtils + .ofFloat(toView, "alpha", 0f, 1f) + .setDuration(fadeDuration); + alphaAnim.setInterpolator(new DecelerateInterpolator(1.5f)); + alphaAnim.addUpdateListener(new AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + if (animation == null) { + throw new RuntimeException("animation is null"); + } + float t = (Float) animation.getAnimatedValue(); + dispatchOnLauncherTransitionStep(fromView, t); + dispatchOnLauncherTransitionStep(toView, t); + } + }); - toView.setVisibility(View.VISIBLE); - toView.setAlpha(0f); - final ObjectAnimator alphaAnim = LauncherAnimUtils - .ofFloat(toView, "alpha", 0f, 1f) - .setDuration(fadeDuration); - alphaAnim.setInterpolator(new DecelerateInterpolator(1.5f)); - alphaAnim.addUpdateListener(new AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - if (animation == null) { - throw new RuntimeException("animation is null"); + // toView should appear right at the end of the workspace shrink + // animation + mStateAnimation = LauncherAnimUtils.createAnimatorSet(); + mStateAnimation.play(scaleAnim).after(startDelay); + mStateAnimation.play(alphaAnim).after(startDelay); + + mStateAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + // Prepare the position + toView.setTranslationX(0.0f); + toView.setTranslationY(0.0f); + toView.setVisibility(View.VISIBLE); + toView.bringToFront(); } - float t = (Float) animation.getAnimatedValue(); - dispatchOnLauncherTransitionStep(fromView, t); - dispatchOnLauncherTransitionStep(toView, t); - } - }); + @Override + public void onAnimationEnd(Animator animation) { + dispatchOnLauncherTransitionEnd(fromView, animated, false); + dispatchOnLauncherTransitionEnd(toView, animated, false); - // toView should appear right at the end of the workspace shrink - // animation - mStateAnimation = LauncherAnimUtils.createAnimatorSet(); - mStateAnimation.play(scaleAnim).after(startDelay); - mStateAnimation.play(alphaAnim).after(startDelay); + // Hide the search bar + if (mSearchDropTargetBar != null) { + mSearchDropTargetBar.hideSearchBar(false); + } + } + }); + } else { + int width = toView.getMeasuredWidth(); + int height = toView.getMeasuredHeight(); + float revealRadius = (float) Math.sqrt((width * width) / 4 + height * height); - mStateAnimation.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - // Prepare the position - toView.setTranslationX(0.0f); - toView.setTranslationY(0.0f); - toView.setVisibility(View.VISIBLE); - toView.bringToFront(); + mStateAnimation = LauncherAnimUtils.createAnimatorSet(); + + AppsCustomizePagedView content = (AppsCustomizePagedView) + toView.findViewById(R.id.apps_customize_pane_content); + + View page = content.getPageAt(content.getCurrentPage()); + View revealView = content; + + float yDrift = height / 2f - 400; + + LauncherViewPropertyAnimator panelAlphaAndDrift = + new LauncherViewPropertyAnimator(revealView); + revealView.setTranslationY(yDrift); + revealView.setAlpha(0.3f); + panelAlphaAndDrift.alpha(1) + .translationY(0) + .setDuration(revealDuration) + .setInterpolator(new LogDecelerateInterpolator(100, 0)); + + mStateAnimation.play(panelAlphaAndDrift); + + if (page instanceof CellLayout) { + CellLayout cellLayout = (CellLayout) page; + cellLayout.enableHardwareLayer(true); + + View iconsView = cellLayout.getShortcutsAndWidgets(); + iconsView.setAlpha(0f); + + LauncherViewPropertyAnimator iconsAlpha = + new LauncherViewPropertyAnimator(iconsView); + iconsAlpha.alpha(1f) + .setDuration(revealDuration - 100) + .setInterpolator(new LogDecelerateInterpolator(100, 0)); + mStateAnimation.play(iconsAlpha); } - @Override - public void onAnimationEnd(Animator animation) { - dispatchOnLauncherTransitionEnd(fromView, animated, false); - dispatchOnLauncherTransitionEnd(toView, animated, false); - // Hide the search bar - if (mSearchDropTargetBar != null) { - mSearchDropTargetBar.hideSearchBar(false); + View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator); + pageIndicators.setAlpha(0f); + final LauncherViewPropertyAnimator indicatorsAlpha = + new LauncherViewPropertyAnimator(pageIndicators); + indicatorsAlpha.alpha(1f); + indicatorsAlpha.setDuration(revealDuration); + mStateAnimation.play(indicatorsAlpha); + + width = revealView.getMeasuredWidth(); + + ValueAnimator reveal = + ViewAnimationUtils.createCircularReveal(revealView, width / 2, + height / 2 + 100, 0f, revealRadius); + reveal.setDuration(revealDuration); + reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); + + toView.setTranslationX(0); + toView.setTranslationY(0); + toView.setAlpha(1f); + // toView should appear right at the end of the workspace shrink + // animation + mStateAnimation.play(reveal); + + reveal.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + // Prepare the position + toView.bringToFront(); + toView.setVisibility(View.VISIBLE); } - } - }); + }); - if (workspaceAnim != null) { - mStateAnimation.play(workspaceAnim); + mStateAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + dispatchOnLauncherTransitionEnd(fromView, animated, false); + dispatchOnLauncherTransitionEnd(toView, animated, false); + + // Hide the search bar + if (mSearchDropTargetBar != null) { + mSearchDropTargetBar.hideSearchBar(false); + } + } + }); } boolean delayAnim = false; - + if (workspaceAnim != null) { + mStateAnimation.play(workspaceAnim); + } dispatchOnLauncherTransitionPrepare(fromView, animated, false); dispatchOnLauncherTransitionPrepare(toView, animated, false); @@ -3305,11 +3402,15 @@ public class Launcher extends Activity mStateAnimation.cancel(); mStateAnimation = null; } + + boolean material = Utilities.isLmp(); + Resources res = getResources(); final int duration = res.getInteger(R.integer.config_appsCustomizeZoomOutTime); - final int fadeOutDuration = - res.getInteger(R.integer.config_appsCustomizeFadeOutTime); + final int fadeOutDuration = res.getInteger(R.integer.config_appsCustomizeFadeOutTime); + final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime); + final float scaleFactor = (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor); final View fromView = mAppsCustomizeTabHost; @@ -3328,31 +3429,116 @@ public class Launcher extends Activity setPivotsForZoom(fromView, scaleFactor); showHotseat(animated); if (animated) { - final LauncherViewPropertyAnimator scaleAnim = - new LauncherViewPropertyAnimator(fromView); - scaleAnim. - scaleX(scaleFactor).scaleY(scaleFactor). - setDuration(duration). - setInterpolator(new Workspace.ZoomInInterpolator()); - - final ObjectAnimator alphaAnim = LauncherAnimUtils - .ofFloat(fromView, "alpha", 1f, 0f) - .setDuration(fadeOutDuration); - alphaAnim.setInterpolator(new AccelerateDecelerateInterpolator()); - alphaAnim.addUpdateListener(new AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float t = 1f - (Float) animation.getAnimatedValue(); - dispatchOnLauncherTransitionStep(fromView, t); - dispatchOnLauncherTransitionStep(toView, t); + if (!material) { + final LauncherViewPropertyAnimator scaleAnim = + new LauncherViewPropertyAnimator(fromView); + scaleAnim. + scaleX(scaleFactor).scaleY(scaleFactor). + setDuration(duration). + setInterpolator(new Workspace.ZoomInInterpolator()); + + final ObjectAnimator alphaAnim = LauncherAnimUtils + .ofFloat(fromView, "alpha", 1f, 0f) + .setDuration(fadeOutDuration); + alphaAnim.setInterpolator(new AccelerateDecelerateInterpolator()); + alphaAnim.addUpdateListener(new AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + float t = 1f - (Float) animation.getAnimatedValue(); + dispatchOnLauncherTransitionStep(fromView, t); + dispatchOnLauncherTransitionStep(toView, t); + } + }); + + mStateAnimation = LauncherAnimUtils.createAnimatorSet(); + + dispatchOnLauncherTransitionPrepare(fromView, animated, true); + dispatchOnLauncherTransitionPrepare(toView, animated, true); + mAppsCustomizeContent.stopScrolling(); + + mStateAnimation.playTogether(scaleAnim, alphaAnim); + } else { + mStateAnimation = LauncherAnimUtils.createAnimatorSet(); + + int width = fromView.getMeasuredWidth(); + int height = fromView.getMeasuredHeight(); + float revealRadius = (float) Math.sqrt((width * width) / 4 + height * height); + + AppsCustomizePagedView content = (AppsCustomizePagedView) + fromView.findViewById(R.id.apps_customize_pane_content); + + final View page = content.getPageAt(content.getNextPage()); + View revealView = page; + + float yDrift = height / 2f - 400; + + LauncherViewPropertyAnimator panelAlphaAndDrift = + new LauncherViewPropertyAnimator(revealView); + revealView.setTranslationY(0); + revealView.setAlpha(1); + panelAlphaAndDrift.alpha(0) + .translationY(yDrift) + .setDuration(revealDuration) + .setInterpolator(new LogDecelerateInterpolator(100, 0)); + + mStateAnimation.play(panelAlphaAndDrift); + + if (page instanceof CellLayout) { + final CellLayout cellLayout = (CellLayout) page; + cellLayout.enableHardwareLayer(true); + + final View iconsView = cellLayout.getShortcutsAndWidgets(); + + LauncherViewPropertyAnimator iconsAlpha = + new LauncherViewPropertyAnimator(iconsView); + iconsAlpha.alpha(0f) + .setDuration(revealDuration - 100) + .setInterpolator(new LogDecelerateInterpolator(100, 0)); + + mStateAnimation.play(iconsAlpha); + + mStateAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + cellLayout.setTranslationY(0); + cellLayout.setAlpha(1f); + iconsView.setAlpha(1f); + } + }); } - }); - mStateAnimation = LauncherAnimUtils.createAnimatorSet(); + View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator); + final LauncherViewPropertyAnimator indicatorsAlpha = + new LauncherViewPropertyAnimator(pageIndicators); + indicatorsAlpha.alpha(0f); + indicatorsAlpha.setDuration(revealDuration); + indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f)); + mStateAnimation.play(indicatorsAlpha); - dispatchOnLauncherTransitionPrepare(fromView, animated, true); - dispatchOnLauncherTransitionPrepare(toView, animated, true); - mAppsCustomizeContent.stopScrolling(); + width = revealView.getMeasuredWidth(); + + ValueAnimator reveal = + ViewAnimationUtils.createCircularReveal(revealView, width / 2, + height / 2 + 100, revealRadius, 0f); + reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); + reveal.setDuration(revealDuration); + + reveal.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + fromView.setVisibility(View.GONE); + } + }); + + dispatchOnLauncherTransitionPrepare(fromView, animated, true); + dispatchOnLauncherTransitionPrepare(toView, animated, true); + mAppsCustomizeContent.stopScrolling(); + + mStateAnimation.play(reveal); + } + if (workspaceAnim != null) { + mStateAnimation.play(workspaceAnim); + } mStateAnimation.addListener(new AnimatorListenerAdapter() { @Override @@ -3367,10 +3553,6 @@ public class Launcher extends Activity } }); - mStateAnimation.playTogether(scaleAnim, alphaAnim); - if (workspaceAnim != null) { - mStateAnimation.play(workspaceAnim); - } dispatchOnLauncherTransitionStart(fromView, animated, true); dispatchOnLauncherTransitionStart(toView, animated, true); LauncherAnimUtils.startAnimationAfterNextDraw(mStateAnimation, toView); @@ -3835,7 +4017,7 @@ public class Launcher extends Activity text.clear(); // Populate event with a fake title based on the current state. if (mState == State.APPS_CUSTOMIZE) { - text.add(mAppsCustomizeTabHost.getCurrentTabView().getContentDescription()); + text.add(mAppsCustomizeTabHost.getContentTag()); } else { text.add(getString(R.string.all_apps_home_button_label)); } diff --git a/src/com/android/launcher3/LogAccelerateInterpolator.java b/src/com/android/launcher3/LogAccelerateInterpolator.java new file mode 100644 index 000000000..c3bbfa536 --- /dev/null +++ b/src/com/android/launcher3/LogAccelerateInterpolator.java @@ -0,0 +1,25 @@ +package com.android.launcher3; + +import android.animation.TimeInterpolator; + +public class LogAccelerateInterpolator implements TimeInterpolator { + + int mBase; + int mDrift; + final float mLogScale; + + public LogAccelerateInterpolator(int base, int drift) { + mBase = base; + mDrift = drift; + mLogScale = 1f / computeLog(1, mBase, mDrift); + } + + static float computeLog(float t, int base, int drift) { + return (float) -Math.pow(base, -t) + 1 + (drift * t); + } + + @Override + public float getInterpolation(float t) { + return 1 - computeLog(1 - t, mBase, mDrift) * mLogScale; + } +} diff --git a/src/com/android/launcher3/LogDecelerateInterpolator.java b/src/com/android/launcher3/LogDecelerateInterpolator.java new file mode 100644 index 000000000..4c5f6f08c --- /dev/null +++ b/src/com/android/launcher3/LogDecelerateInterpolator.java @@ -0,0 +1,26 @@ +package com.android.launcher3; + +import android.animation.TimeInterpolator; + +public class LogDecelerateInterpolator implements TimeInterpolator { + + int mBase; + int mDrift; + final float mLogScale; + + public LogDecelerateInterpolator(int base, int drift) { + mBase = base; + mDrift = drift; + + mLogScale = 1f / computeLog(1, mBase, mDrift); + } + + static float computeLog(float t, int base, int drift) { + return (float) -Math.pow(base, -t) + 1 + (drift * t); + } + + @Override + public float getInterpolation(float t) { + return computeLog(t, mBase, mDrift) * mLogScale; + } +} diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index a8e7580c3..945a92eb5 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -109,9 +109,6 @@ public class Workspace extends SmoothPagedView // These properties refer to the background protection gradient used for AllApps and Customize private ValueAnimator mBackgroundFadeInAnimation; private ValueAnimator mBackgroundFadeOutAnimation; - private Drawable mBackground; - boolean mDrawBackground = true; - private float mBackgroundAlpha = 0; private static final long CUSTOM_CONTENT_GESTURE_DELAY = 200; private long mTouchDownTime = -1; @@ -191,7 +188,7 @@ public class Workspace extends SmoothPagedView // State variable that indicates whether the pages are small (ie when you're // in all apps or customize mode) - enum State { NORMAL, SPRING_LOADED, SMALL, OVERVIEW}; + enum State { NORMAL, NORMAL_HIDDEN, SPRING_LOADED, OVERVIEW, OVERVIEW_HIDDEN}; private State mState = State.NORMAL; private boolean mIsSwitchingState = false; @@ -445,13 +442,6 @@ public class Workspace extends SmoothPagedView setMinScale(mOverviewModeShrinkFactor); setupLayoutTransition(); - final Resources res = getResources(); - try { - mBackground = res.getDrawable(R.drawable.apps_customize_bg); - } catch (Resources.NotFoundException e) { - // In this case, we will skip drawing background protection - } - mWallpaperOffset = new WallpaperOffsetInterpolator(); Display display = mLauncher.getWindowManager().getDefaultDisplay(); display.getSize(mDisplaySize); @@ -1068,8 +1058,8 @@ public class Workspace extends SmoothPagedView */ @Override public boolean onTouch(View v, MotionEvent event) { - return (isSmall() || !isFinishedSwitchingState()) - || (!isSmall() && indexOfChild(v) != mCurrentPage); + return (workspaceInModalState() || !isFinishedSwitchingState()) + || (!workspaceInModalState() && indexOfChild(v) != mCurrentPage); } public boolean isSwitchingState() { @@ -1088,7 +1078,7 @@ public class Workspace extends SmoothPagedView @Override public boolean dispatchUnhandledMove(View focused, int direction) { - if (isSmall() || !isFinishedSwitchingState()) { + if (workspaceInModalState() || !isFinishedSwitchingState()) { // when the home screens are shrunken, shouldn't allow side-scrolling return false; } @@ -1226,7 +1216,7 @@ public class Workspace extends SmoothPagedView } if (mDragController.isDragging()) { - if (isSmall()) { + if (workspaceInModalState()) { // If we are in springloaded mode, then force an event to check if the current touch // is under a new page (to scroll to) mDragController.forceTouchMove(); @@ -1500,7 +1490,7 @@ public class Workspace extends SmoothPagedView } void showOutlines() { - if (!isSmall() && !mIsSwitchingState) { + if (!workspaceInModalState() && !mIsSwitchingState) { if (mChildrenOutlineFadeOutAnimation != null) mChildrenOutlineFadeOutAnimation.cancel(); if (mChildrenOutlineFadeInAnimation != null) mChildrenOutlineFadeInAnimation.cancel(); mChildrenOutlineFadeInAnimation = LauncherAnimUtils.ofFloat(this, "childrenOutlineAlpha", 1.0f); @@ -1510,7 +1500,7 @@ public class Workspace extends SmoothPagedView } void hideOutlines() { - if (!isSmall() && !mIsSwitchingState) { + if (!workspaceInModalState() && !mIsSwitchingState) { if (mChildrenOutlineFadeInAnimation != null) mChildrenOutlineFadeInAnimation.cancel(); if (mChildrenOutlineFadeOutAnimation != null) mChildrenOutlineFadeOutAnimation.cancel(); mChildrenOutlineFadeOutAnimation = LauncherAnimUtils.ofFloat(this, "childrenOutlineAlpha", 0.0f); @@ -1538,15 +1528,9 @@ public class Workspace extends SmoothPagedView return mChildrenOutlineAlpha; } - void disableBackground() { - mDrawBackground = false; - } - void enableBackground() { - mDrawBackground = true; - } - private void animateBackgroundGradient(float finalAlpha, boolean animated) { - if (mBackground == null) return; + final DragLayer dragLayer = mLauncher.getDragLayer(); + if (mBackgroundFadeInAnimation != null) { mBackgroundFadeInAnimation.cancel(); mBackgroundFadeInAnimation = null; @@ -1555,36 +1539,26 @@ public class Workspace extends SmoothPagedView mBackgroundFadeOutAnimation.cancel(); mBackgroundFadeOutAnimation = null; } - float startAlpha = getBackgroundAlpha(); + float startAlpha = dragLayer.getBackgroundAlpha(); if (finalAlpha != startAlpha) { if (animated) { mBackgroundFadeOutAnimation = LauncherAnimUtils.ofFloat(this, startAlpha, finalAlpha); mBackgroundFadeOutAnimation.addUpdateListener(new AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { - setBackgroundAlpha(((Float) animation.getAnimatedValue()).floatValue()); + dragLayer.setBackgroundAlpha( + ((Float)animation.getAnimatedValue()).floatValue()); } }); mBackgroundFadeOutAnimation.setInterpolator(new DecelerateInterpolator(1.5f)); mBackgroundFadeOutAnimation.setDuration(BACKGROUND_FADE_OUT_DURATION); mBackgroundFadeOutAnimation.start(); } else { - setBackgroundAlpha(finalAlpha); + dragLayer.setBackgroundAlpha(finalAlpha); } } } - public void setBackgroundAlpha(float alpha) { - if (alpha != mBackgroundAlpha) { - mBackgroundAlpha = alpha; - invalidate(); - } - } - - public float getBackgroundAlpha() { - return mBackgroundAlpha; - } - float backgroundAlphaInterpolator(float r) { float pivotA = 0.1f; float pivotB = 0.4f; @@ -1656,13 +1630,13 @@ public class Workspace extends SmoothPagedView if (Float.compare(progress, mLastCustomContentScrollProgress) == 0) return; CellLayout cc = mWorkspaceScreens.get(CUSTOM_CONTENT_SCREEN_ID); - if (progress > 0 && cc.getVisibility() != VISIBLE && !isSmall()) { + if (progress > 0 && cc.getVisibility() != VISIBLE && !workspaceInModalState()) { cc.setVisibility(VISIBLE); } mLastCustomContentScrollProgress = progress; - setBackgroundAlpha(progress * 0.8f); + mLauncher.getDragLayer().setBackgroundAlpha(progress * 0.8f); if (mLauncher.getHotseat() != null) { mLauncher.getHotseat().setTranslationX(translationX); @@ -1792,25 +1766,12 @@ public class Workspace extends SmoothPagedView @Override protected void onDraw(Canvas canvas) { - // Draw the background gradient if necessary - if (mBackground != null && mBackgroundAlpha > 0.0f && mDrawBackground) { - int alpha = (int) (mBackgroundAlpha * 255); - mBackground.setAlpha(alpha); - mBackground.setBounds(getScrollX(), 0, getScrollX() + getMeasuredWidth(), - getMeasuredHeight()); - mBackground.draw(canvas); - } - super.onDraw(canvas); // Call back to LauncherModel to finish binding after the first draw post(mBindPages); } - boolean isDrawingBackgroundGradient() { - return (mBackground != null && mBackgroundAlpha > 0.0f && mDrawBackground); - } - @Override protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { if (!mLauncher.isAllAppsVisible()) { @@ -1826,7 +1787,7 @@ public class Workspace extends SmoothPagedView @Override public int getDescendantFocusability() { - if (isSmall()) { + if (workspaceInModalState()) { return ViewGroup.FOCUS_BLOCK_DESCENDANTS; } return super.getDescendantFocusability(); @@ -1844,8 +1805,8 @@ public class Workspace extends SmoothPagedView } } - public boolean isSmall() { - return mState == State.SMALL || mState == State.SPRING_LOADED || mState == State.OVERVIEW; + public boolean workspaceInModalState() { + return mState != State.NORMAL; } void enableChildrenCache(int fromPage, int toPage) { @@ -1880,7 +1841,7 @@ public class Workspace extends SmoothPagedView } private void updateChildrenLayersEnabled(boolean force) { - boolean small = mState == State.SMALL || mState == State.OVERVIEW || mIsSwitchingState; + boolean small = mState == State.OVERVIEW || mIsSwitchingState; boolean enableChildrenLayers = force || small || mAnimatingViewIntoPlace || isPageMoving(); if (enableChildrenLayers != mChildrenLayersEnabled) { @@ -2223,6 +2184,8 @@ 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) { if (mState == state) { return null; @@ -2236,21 +2199,25 @@ public class Workspace extends SmoothPagedView final State oldState = mState; final boolean oldStateIsNormal = (oldState == State.NORMAL); final boolean oldStateIsSpringLoaded = (oldState == State.SPRING_LOADED); - final boolean oldStateIsSmall = (oldState == State.SMALL); + 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 stateIsSmall = (state == State.SMALL); + 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 = (stateIsOverview || stateIsSmall) ? 0f : 1f; + float finalHotseatAndPageIndicatorAlpha = (stateIsNormal || stateIsSpringLoaded) ? 1f : 0f; float finalOverviewPanelAlpha = stateIsOverview ? 1f : 0f; float finalSearchBarAlpha = !stateIsNormal ? 0f : 1f; - float finalWorkspaceTranslationY = stateIsOverview ? getOverviewModeTranslationY() : 0; + float finalWorkspaceTranslationY = stateIsOverview || stateIsOverviewHidden ? + getOverviewModeTranslationY() : 0; - boolean workspaceToAllApps = (oldStateIsNormal && stateIsSmall); - boolean allAppsToWorkspace = (oldStateIsSmall && stateIsNormal); + boolean workspaceToAllApps = (oldStateIsNormal && stateIsNormalHidden); + boolean overviewToAllApps = (oldStateIsOverview && stateIsOverviewHidden); + boolean allAppsToWorkspace = (stateIsNormalHidden && stateIsNormal); boolean workspaceToOverview = (oldStateIsNormal && stateIsOverview); boolean overviewToWorkspace = (oldStateIsOverview && stateIsNormal); @@ -2265,10 +2232,8 @@ public class Workspace extends SmoothPagedView if (state != State.NORMAL) { if (stateIsSpringLoaded) { mNewScale = mSpringLoadedShrinkFactor; - } else if (stateIsOverview) { + } else if (stateIsOverview || stateIsOverviewHidden) { mNewScale = mOverviewModeShrinkFactor; - } else if (stateIsSmall){ - mNewScale = mOverviewModeShrinkFactor - 0.3f; } if (workspaceToAllApps) { updateChildrenLayersEnabled(false); @@ -2276,8 +2241,8 @@ public class Workspace extends SmoothPagedView } final int duration; - if (workspaceToAllApps) { - duration = getResources().getInteger(R.integer.config_workspaceUnshrinkTime); + 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 { @@ -2294,7 +2259,7 @@ public class Workspace extends SmoothPagedView boolean isCurrentPage = (i == snapPage); float initialAlpha = cl.getShortcutsAndWidgets().getAlpha(); float finalAlpha; - if (stateIsSmall) { + if (stateIsNormalHidden || stateIsOverviewHidden) { finalAlpha = 0f; } else if (stateIsNormal && mWorkspaceFadeInAdjacentScreens) { finalAlpha = (i == snapPage || i < numCustomPages()) ? 1f : 0f; @@ -2331,11 +2296,11 @@ public class Workspace extends SmoothPagedView final View hotseat = mLauncher.getHotseat(); final View pageIndicator = getPageIndicator(); if (animated) { - anim.setDuration(duration); 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++) { @@ -2350,6 +2315,7 @@ public class Workspace extends SmoothPagedView LauncherViewPropertyAnimator alphaAnim = new LauncherViewPropertyAnimator(cl.getShortcutsAndWidgets()); alphaAnim.alpha(mNewAlphas[i]) + .setDuration(duration) .setInterpolator(mZoomInInterpolator); anim.play(alphaAnim); } @@ -2358,6 +2324,7 @@ public class Workspace extends SmoothPagedView 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( @@ -2400,7 +2367,11 @@ public class Workspace extends SmoothPagedView hotseatAlpha.setInterpolator(null); overviewPanelAlpha.setInterpolator(new DecelerateInterpolator(2)); } - searchBarAlpha.setInterpolator(null); + + overviewPanelAlpha.setDuration(duration); + pageIndicatorAlpha.setDuration(duration); + hotseatAlpha.setDuration(duration); + searchBarAlpha.setDuration(duration); anim.play(overviewPanelAlpha); anim.play(hotseatAlpha); @@ -2425,18 +2396,11 @@ public class Workspace extends SmoothPagedView } mLauncher.updateVoiceButtonProxyVisible(false); - if (stateIsSpringLoaded) { - // Right now we're covered by Apps Customize - // Show the background gradient immediately, so the gradient will - // be showing once AppsCustomize disappears - animateBackgroundGradient(getResources().getInteger( - R.integer.config_appsCustomizeSpringLoadedBgAlpha) / 100f, false); - } else if (stateIsOverview) { - animateBackgroundGradient(getResources().getInteger( - R.integer.config_appsCustomizeSpringLoadedBgAlpha) / 100f, true); - } else { - // Fade the background gradient away + if (stateIsNormal) { animateBackgroundGradient(0f, animated); + } else { + animateBackgroundGradient(getResources().getInteger( + R.integer.config_workspaceScrimAlpha) / 100f, animated); } return anim; } @@ -2822,7 +2786,8 @@ public class Workspace extends SmoothPagedView } public boolean transitionStateShouldAllowDrop() { - return ((!isSwitchingState() || mTransitionProgress > 0.5f) && mState != State.SMALL); + return ((!isSwitchingState() || mTransitionProgress > 0.5f) && + (mState == State.NORMAL || mState == State.SPRING_LOADED)); } /** @@ -3591,7 +3556,7 @@ public class Workspace extends SmoothPagedView public void onDragOver(DragObject d) { // Skip drag over events while we are dragging over side pages - if (mInScrollArea || mIsSwitchingState || mState == State.SMALL) return; + if (mInScrollArea || !transitionStateShouldAllowDrop()) return; Rect r = new Rect(); CellLayout layout = null; @@ -3604,7 +3569,7 @@ public class Workspace extends SmoothPagedView final View child = (mDragInfo == null) ? null : mDragInfo.cell; // Identify whether we have dragged over a side page - if (isSmall()) { + if (workspaceInModalState()) { if (mLauncher.getHotseat() != null && !isExternalDragWidget(d)) { if (isPointInSelfOverHotseat(d.x, d.y, r)) { layout = mLauncher.getHotseat().getLayout(); @@ -4482,7 +4447,7 @@ public class Workspace extends SmoothPagedView @Override public void scrollLeft() { - if (!isSmall() && !mIsSwitchingState) { + if (!workspaceInModalState() && !mIsSwitchingState) { super.scrollLeft(); } Folder openFolder = getOpenFolder(); @@ -4493,7 +4458,7 @@ public class Workspace extends SmoothPagedView @Override public void scrollRight() { - if (!isSmall() && !mIsSwitchingState) { + if (!workspaceInModalState() && !mIsSwitchingState) { super.scrollRight(); } Folder openFolder = getOpenFolder(); @@ -4515,7 +4480,7 @@ public class Workspace extends SmoothPagedView } boolean result = false; - if (!isSmall() && !mIsSwitchingState && getOpenFolder() == null) { + if (!workspaceInModalState() && !mIsSwitchingState && getOpenFolder() == null) { mInScrollArea = true; final int page = getNextPage() + @@ -4895,7 +4860,7 @@ public class Workspace extends SmoothPagedView } private void moveToScreen(int page, boolean animate) { - if (!isSmall()) { + if (!workspaceInModalState()) { if (animate) { snapToPage(page); } else { -- cgit v1.2.3