summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Cohen <adamcohen@google.com>2013-07-23 16:47:31 -0700
committerAdam Cohen <adamcohen@google.com>2013-08-13 18:53:36 -0700
commitf358a4bbd6ce5b6ddadfae19e6b9c6872530d627 (patch)
tree90417a875d6fb75d634c49e0272a90a867d6b0a0
parent695ff6b6fada4e1037592d7c4961321e12890b7d (diff)
downloadandroid_packages_apps_Trebuchet-f358a4bbd6ce5b6ddadfae19e6b9c6872530d627.zip
android_packages_apps_Trebuchet-f358a4bbd6ce5b6ddadfae19e6b9c6872530d627.tar.gz
android_packages_apps_Trebuchet-f358a4bbd6ce5b6ddadfae19e6b9c6872530d627.tar.bz2
Adding overview mode for reordering, widget adding and wallpaper switching
Change-Id: I082ba0b90ca4b3fbba32e8dfdec8ba79486d841c
-rw-r--r--res/layout-land/launcher.xml4
-rw-r--r--res/layout-port/launcher.xml24
-rw-r--r--res/layout-sw720dp/launcher.xml24
-rw-r--r--res/layout/overview_panel.xml39
-rw-r--r--res/values/config.xml2
-rw-r--r--res/values/dimens.xml2
-rw-r--r--res/values/strings.xml5
-rw-r--r--src/com/android/launcher3/Launcher.java52
-rw-r--r--src/com/android/launcher3/PagedView.java415
-rw-r--r--src/com/android/launcher3/Workspace.java138
10 files changed, 415 insertions, 290 deletions
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index 8ee1413..3454ad4 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -65,6 +65,10 @@
android:id="@+id/qsb_bar"
layout="@layout/qsb_bar" />
+ <include layout="@layout/overview_panel"
+ android:id="@+id/overview_panel"
+ android:visibility="gone" />
+
<!-- The Workspace cling must appear under the AppsCustomizePagedView below to ensure
that it is still visible during the transition to AllApps and doesn't overlay on
top of that view. -->
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index 0fee045..a2e8298 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -30,16 +30,6 @@
android:layout_height="match_parent"
android:fitsSystemWindows="true">
- <!-- Keep these behind the workspace so that they are not visible when
- we go into AllApps -->
- <include
- android:id="@+id/page_indicator"
- layout="@layout/page_indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom|center_horizontal"
- android:layout_marginBottom="@dimen/button_bar_height_plus_padding" />
-
<!-- The workspace contains 5 screens of cells -->
<com.android.launcher3.Workspace
android:id="@+id/workspace"
@@ -65,6 +55,20 @@
android:layout_height="@dimen/button_bar_height_plus_padding"
android:layout_gravity="bottom" />
+ <include layout="@layout/overview_panel"
+ android:id="@+id/overview_panel"
+ android:visibility="gone" />
+
+ <!-- Keep these behind the workspace so that they are not visible when
+ we go into AllApps -->
+ <include
+ android:id="@+id/page_indicator"
+ layout="@layout/page_indicator"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|center_horizontal"
+ android:layout_marginBottom="@dimen/button_bar_height_plus_padding" />
+
<include
android:id="@+id/qsb_bar"
layout="@layout/qsb_bar" />
diff --git a/res/layout-sw720dp/launcher.xml b/res/layout-sw720dp/launcher.xml
index 852d1ec..82f0178 100644
--- a/res/layout-sw720dp/launcher.xml
+++ b/res/layout-sw720dp/launcher.xml
@@ -30,16 +30,6 @@
android:layout_height="match_parent"
android:fitsSystemWindows="true">
- <!-- Keep these behind the workspace so that they are not visible when
- we go into AllApps -->
- <include
- android:id="@+id/page_indicator"
- layout="@layout/page_indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom|center_horizontal"
- android:layout_marginBottom="@dimen/button_bar_height_plus_padding" />
-
<!-- The workspace contains 5 screens of cells -->
<com.android.launcher3.Workspace
android:id="@+id/workspace"
@@ -69,6 +59,20 @@
android:id="@+id/qsb_bar"
layout="@layout/qsb_bar" />
+ <include layout="@layout/overview_panel"
+ android:id="@+id/overview_panel"
+ android:visibility="gone" />
+
+ <!-- Keep these behind the workspace so that they are not visible when
+ we go into AllApps -->
+ <include
+ android:id="@+id/page_indicator"
+ layout="@layout/page_indicator"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|center_horizontal"
+ android:layout_marginBottom="@dimen/button_bar_height_plus_padding" />
+
<!-- The Workspace cling must appear under the AppsCustomizePagedView below to ensure
that it is still visible during the transition to AllApps and doesn't overlay on
top of that view. -->
diff --git a/res/layout/overview_panel.xml b/res/layout/overview_panel.xml
new file mode 100644
index 0000000..713adea
--- /dev/null
+++ b/res/layout/overview_panel.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_gravity="center_horizontal|bottom"
+ android:paddingBottom="@dimen/overview_panel_bottom_padding">
+
+ <TextView
+ android:id="@+id/widget_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/widget_button_text"
+ android:textSize="18dp"/>
+ <Space
+ android:layout_width="@dimen/overview_panel_buttonSpacing"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/wallpaper_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/wallpaper_button_text"
+ android:textSize="18dp" />
+</LinearLayout>
diff --git a/res/values/config.xml b/res/values/config.xml
index cc3d4f0..2fc3473 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -15,6 +15,8 @@
<integer name="config_workspaceUnshrinkTime">300</integer>
<!-- Out of 100, the percent to shrink the workspace during spring loaded mode. -->
<integer name="config_workspaceSpringLoadShrinkPercentage">80</integer>
+ <!-- Out of 100, the percent to shrink the workspace during overview mode. -->
+ <integer name="config_workspaceOverviewShrinkPercentage">50</integer>
<!-- Fade/zoom in/out duration & scale in the AllApps transition.
Note: This should be less than the workspaceShrinkTime as they happen together. -->
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 2bfb31c..13a15e3 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -50,6 +50,8 @@
<dimen name="workspace_overscroll_drawable_padding">0dp</dimen>
<dimen name="workspace_icon_text_size">12sp</dimen>
<dimen name="workspace_spring_loaded_page_spacing">15dp</dimen>
+ <dimen name="overview_panel_bottom_padding">50dp</dimen>
+ <dimen name="overview_panel_buttonSpacing">40dp</dimen>
<dimen name="app_icon_drawable_padding">6dp</dimen>
<dimen name="app_icon_drawable_padding_land">2dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 052e13b..51da40b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -282,4 +282,9 @@ s -->
<!-- Debug-only activity name. [DO NOT TRANSLATE] -->
<string name="debug_memory_activity">* HPROF</string>
+ <!-- Strings for the customization mode -->
+ <!-- Text for widget add button -->
+ <string name="widget_button_text">Add Widget</string>
+ <!-- Text for wallpaper change button -->
+ <string name="wallpaper_button_text">Wallpaper</string>
</resources>
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index f990d25..09881b6 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -79,6 +79,7 @@ import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
@@ -236,6 +237,8 @@ public class Launcher extends Activity
private FolderInfo mFolderInfo;
private Hotseat mHotseat;
+ private View mOverviewPanel;
+
private View mAllAppsButton;
private SearchDropTargetBar mSearchDropTargetBar;
@@ -1065,6 +1068,20 @@ public class Launcher extends Activity
mHotseat.setup(this);
}
+ mOverviewPanel = findViewById(R.id.overview_panel);
+ findViewById(R.id.widget_button).setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ showAllApps(true);
+ }
+ });
+ findViewById(R.id.wallpaper_button).setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ startWallpaper();
+ }
+ });
+
// Setup the workspace
mWorkspace.setHapticFeedbackEnabled(false);
mWorkspace.setOnLongClickListener(this);
@@ -1560,6 +1577,9 @@ public class Launcher extends Activity
// otherwise, just wait until onResume to set the state back to Workspace
if (alreadyOnHome) {
showWorkspace(true);
+ if (mWorkspace.isInOverviewMode()) {
+ mWorkspace.exitOverviewMode();
+ }
} else {
mOnResumeState = State.WORKSPACE;
}
@@ -2050,6 +2070,8 @@ public class Launcher extends Activity
public void onBackPressed() {
if (isAllAppsVisible()) {
showWorkspace(true);
+ } else if (mWorkspace.isInOverviewMode()) {
+ mWorkspace.exitOverviewMode();
} else if (mWorkspace.getOpenFolder() != null) {
Folder openFolder = mWorkspace.getOpenFolder();
if (openFolder.isEditingName()) {
@@ -2090,6 +2112,19 @@ public class Launcher extends Activity
return;
}
+ if (v instanceof PageIndicator) {
+ if (!mWorkspace.isInOverviewMode()) {
+ mWorkspace.enterOverviewMode();
+ }
+ return;
+ }
+
+ if (v instanceof CellLayout) {
+ if (mWorkspace.isInOverviewMode()) {
+ mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v));
+ }
+ }
+
Object tag = v.getTag();
if (tag instanceof ShortcutInfo) {
// Open shortcut
@@ -2138,11 +2173,6 @@ public class Launcher extends Activity
}
public boolean onTouch(View v, MotionEvent event) {
- // this is an intercepted event being forwarded from mWorkspace;
- // clicking anywhere on the workspace causes the customization drawer to slide down
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- showWorkspace(true);
- }
return false;
}
@@ -2510,10 +2540,10 @@ public class Launcher extends Activity
mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
// Disabling reordering until we sort out some issues.
- if (mWorkspace.getIdForScreen((CellLayout) v) >= 0) {
- mWorkspace.startReordering();
+ if (mWorkspace.isInOverviewMode()) {
+ mWorkspace.startReordering(v);
} else {
- startWallpaper();
+ mWorkspace.enterOverviewMode();
}
} else {
if (!(itemUnderLongClick instanceof Folder)) {
@@ -2532,6 +2562,9 @@ public class Launcher extends Activity
Hotseat getHotseat() {
return mHotseat;
}
+ View getOverviewPanel() {
+ return mOverviewPanel;
+ }
SearchDropTargetBar getSearchBar() {
return mSearchDropTargetBar;
}
@@ -2852,11 +2885,10 @@ public class Launcher extends Activity
final View fromView = mAppsCustomizeTabHost;
final View toView = mWorkspace;
Animator workspaceAnim = null;
-
if (toState == State.WORKSPACE) {
int stagger = res.getInteger(R.integer.config_appsCustomizeWorkspaceAnimationStagger);
workspaceAnim = mWorkspace.getChangeStateAnimation(
- Workspace.State.NORMAL, animated, stagger);
+ Workspace.State.NORMAL, animated, stagger, -1);
} else if (toState == State.APPS_CUSTOMIZE_SPRING_LOADED) {
workspaceAnim = mWorkspace.getChangeStateAnimation(
Workspace.State.SPRING_LOADED, animated);
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index bb596a7..ccf2156 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -88,9 +88,13 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// We are disabling touch interaction of the widget region for factory ROM.
private static final boolean DISABLE_TOUCH_INTERACTION = false;
- private static final boolean DISABLE_TOUCH_SIDE_PAGES = false;
+ private static final boolean DISABLE_TOUCH_SIDE_PAGES = true;
private static final boolean DISABLE_FLING_TO_DELETE = true;
+ private boolean mFreeScroll = false;
+ private int mFreeScrollMinScrollX = -1;
+ private int mFreeScrollMaxScrollX = -1;
+
static final int AUTOMATIC_PAGE_SPACING = -1;
protected int mFlingThresholdVelocity;
@@ -117,6 +121,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
private float mDownMotionX;
private float mDownMotionY;
private float mDownScrollX;
+ private float mDragViewBaselineLeft;
protected float mLastMotionX;
protected float mLastMotionXRemainder;
protected float mLastMotionY;
@@ -205,9 +210,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
private int REORDERING_DROP_REPOSITION_DURATION = 200;
protected int REORDERING_REORDER_REPOSITION_DURATION = 300;
protected int REORDERING_ZOOM_IN_OUT_DURATION = 250;
- private int REORDERING_SIDE_PAGE_HOVER_TIMEOUT = 300;
- private float REORDERING_SIDE_PAGE_BUFFER_PERCENTAGE = 0.1f;
- private long REORDERING_DELETE_DROP_TARGET_FADE_DURATION = 150;
+ private int REORDERING_SIDE_PAGE_HOVER_TIMEOUT = 80;
private float mMinScale = 1f;
protected View mDragView;
protected AnimatorSet mZoomInOutAnim;
@@ -223,11 +226,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
private int mPostReorderingPreZoomInRemainingAnimationCount;
private Runnable mPostReorderingPreZoomInRunnable;
- // Edge swiping
- private boolean mOnlyAllowEdgeSwipes = false;
- private boolean mDownEventOnEdge = false;
- private int mEdgeSwipeRegionSize = 0;
-
// Convenience/caching
private Matrix mTmpInvMatrix = new Matrix();
private float[] mTmpPoint = new float[2];
@@ -332,7 +330,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
for (int i = 0; i < getChildCount(); ++i) {
markers.add(getPageIndicatorMarker(i));
}
+
mPageIndicator.addMarkers(markers);
+ mPageIndicator.setOnClickListener((Launcher) getContext());
}
}
@@ -363,12 +363,16 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
void updateDragViewTranslationDuringDrag() {
- float x = mLastMotionX - mDownMotionX + getScrollX() - mDownScrollX;
- float y = mLastMotionY - mDownMotionY;
- mDragView.setTranslationX(x);
- mDragView.setTranslationY(y);
+ if (mDragView != null) {
+ float x = (mLastMotionX - mDownMotionX) + (getScrollX() - mDownScrollX) +
+ (mDragViewBaselineLeft - mDragView.getLeft());
+ float y = mLastMotionY - mDownMotionY;
+ mDragView.setTranslationX(x);
+ mDragView.setTranslationY(y);
- if (DEBUG) Log.d(TAG, "PagedView.updateDragViewTranslationDuringDrag(): " + x + ", " + y);
+ if (DEBUG) Log.d(TAG, "PagedView.updateDragViewTranslationDuringDrag(): "
+ + x + ", " + y);
+ }
}
public void setMinScale(float f) {
@@ -580,6 +584,12 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
@Override
public void scrollTo(int x, int y) {
+ // In free scroll mode, we clamp the scrollX
+ if (mFreeScroll) {
+ x = Math.min(x, mFreeScrollMaxScrollX);
+ x = Math.max(x, mFreeScrollMinScrollX);
+ }
+
final boolean isRtl = isLayoutRtl();
mUnboundedScrollX = x;
@@ -627,7 +637,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
if (getScrollX() != mScroller.getCurrX()
|| getScrollY() != mScroller.getCurrY()
|| mOverScrollX != mScroller.getCurrX()) {
- scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
+ float scaleX = mFreeScroll ? getScaleX() : 1f;
+ int scrollX = (int) (mScroller.getCurrX() * (1 / scaleX));
+ scrollTo(scrollX, mScroller.getCurrY());
}
invalidate();
return true;
@@ -899,6 +911,10 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
}
mChildCountOnLastLayout = getChildCount();
+
+ if (isReordering(true)) {
+ updateDragViewTranslationDuringDrag();
+ }
}
protected void screenScrolled(int screenCenter) {
@@ -991,7 +1007,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
return offset;
}
- void getReorderablePages(int[] range) {
+ protected void getOverviewModePages(int[] range) {
range[0] = 0;
range[1] = getChildCount() - 1;
}
@@ -1217,17 +1233,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
return mTmpRect.contains(x, y);
}
- /** Returns whether x and y originated within the current page view bounds */
- private boolean isTouchPointInCurrentPage(int x, int y) {
- View v = getPageAt(getCurrentPage());
- if (v != null) {
- mTmpRect.set((v.getLeft() - getScrollX()), 0, (v.getRight() - getScrollX()),
- v.getBottom());
- return mTmpRect.contains(x, y);
- }
- return false;
- }
-
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (DISABLE_TOUCH_INTERACTION) {
@@ -1288,13 +1293,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mTotalMotionX = 0;
mActivePointerId = ev.getPointerId(0);
- // Determine if the down event is within the threshold to be an edge swipe
- int leftEdgeBoundary = getViewportOffsetX() + mEdgeSwipeRegionSize;
- int rightEdgeBoundary = getMeasuredWidth() - getViewportOffsetX() - mEdgeSwipeRegionSize;
- if ((mDownMotionX <= leftEdgeBoundary || mDownMotionX >= rightEdgeBoundary)) {
- mDownEventOnEdge = true;
- }
-
/*
* If being flinged and user touches the screen, initiate drag;
* otherwise don't. mScroller.isFinished should be false when
@@ -1332,10 +1330,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
resetTouchState();
- // Just intercept the touch event on up if we tap outside the strict viewport
- if (!isTouchPointInCurrentPage((int) mLastMotionX, (int) mLastMotionY)) {
- return true;
- }
break;
case MotionEvent.ACTION_POINTER_UP:
@@ -1369,10 +1363,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
final float y = ev.getY(pointerIndex);
if (!isTouchPointInViewportWithBuffer((int) x, (int) y)) return;
- // If we're only allowing edge swipes, we break out early if the down event wasn't
- // at the edge.
- if (mOnlyAllowEdgeSwipes && !mDownEventOnEdge) return;
-
final int xDiff = (int) Math.abs(x - mLastMotionX);
final int yDiff = (int) Math.abs(y - mLastMotionY);
@@ -1509,6 +1499,75 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
return OVERSCROLL_DAMP_FACTOR * f;
}
+ protected void enableFreeScroll() {
+ setEnableFreeScroll(true, -1);
+ }
+
+ protected void disableFreeScroll(int snapPage) {
+ setEnableFreeScroll(false, snapPage);
+ }
+
+ private void setEnableFreeScroll(boolean freeScroll, int snapPage) {
+ mFreeScroll = freeScroll;
+
+ if (snapPage == -1) {
+ snapPage = getPageNearestToCenterOfScreen();
+ }
+
+ getOverviewModePages(mTempVisiblePagesRange);
+ if (!mFreeScroll) {
+ snapToPage(snapPage);
+
+ for (int i = 0; i < getPageCount(); ++i) {
+ if (i < mTempVisiblePagesRange[0] || i > mTempVisiblePagesRange[1]) {
+ getPageAt(i).setAlpha(1f);
+ }
+ }
+ } else {
+ mFreeScrollMinScrollX = getScrollForPage(mTempVisiblePagesRange[0]);
+ mFreeScrollMaxScrollX = getScrollForPage(mTempVisiblePagesRange[1]);
+
+ for (int i = 0; i < getPageCount(); ++i) {
+ if (i < mTempVisiblePagesRange[0] || i > mTempVisiblePagesRange[1]) {
+ getPageAt(i).setAlpha(0f);
+ }
+ }
+
+ if (getCurrentPage() < mTempVisiblePagesRange[0]) {
+ setCurrentPage(mTempVisiblePagesRange[0]);
+ } else if (getCurrentPage() > mTempVisiblePagesRange[1]) {
+ setCurrentPage(mTempVisiblePagesRange[1]);
+ }
+ }
+
+ setEnableOverscroll(!freeScroll);
+ }
+
+ private void setEnableOverscroll(boolean enable) {
+ mAllowOverScroll = enable;
+ }
+
+ int getNearestHoverOverPageIndex() {
+ if (mDragView != null) {
+ int dragX = (int) (mDragView.getLeft() + (mDragView.getMeasuredWidth() / 2)
+ + mDragView.getTranslationX());
+ getOverviewModePages(mTempVisiblePagesRange);
+ int minDistance = Integer.MAX_VALUE;
+ int minIndex = indexOfChild(mDragView);
+ for (int i = mTempVisiblePagesRange[0]; i <= mTempVisiblePagesRange[1]; i++) {
+ View page = getPageAt(i);
+ int pageX = (int) (page.getLeft() + page.getMeasuredWidth() / 2);
+ int d = Math.abs(dragX - pageX);
+ if (d < minDistance) {
+ minIndex = i;
+ minDistance = d;
+ }
+ }
+ return minIndex;
+ }
+ return -1;
+ }
+
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (DISABLE_TOUCH_INTERACTION) {
@@ -1543,13 +1602,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mTotalMotionX = 0;
mActivePointerId = ev.getPointerId(0);
- // Determine if the down event is within the threshold to be an edge swipe
- int leftEdgeBoundary = getViewportOffsetX() + mEdgeSwipeRegionSize;
- int rightEdgeBoundary = getMeasuredWidth() - getViewportOffsetX() - mEdgeSwipeRegionSize;
- if ((mDownMotionX <= leftEdgeBoundary || mDownMotionX >= rightEdgeBoundary)) {
- mDownEventOnEdge = true;
- }
-
if (mTouchState == TOUCH_STATE_SCROLLING) {
pageBeginMoving();
}
@@ -1598,38 +1650,23 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// Find the closest page to the touch point
final int dragViewIndex = indexOfChild(mDragView);
- int bufferSize = (int) (REORDERING_SIDE_PAGE_BUFFER_PERCENTAGE *
- getViewportWidth());
- int leftBufferEdge = (int) (mapPointFromViewToParent(this, mViewport.left, 0)[0]
- + bufferSize);
- int rightBufferEdge = (int) (mapPointFromViewToParent(this, mViewport.right, 0)[0]
- - bufferSize);
// Change the drag view if we are hovering over the drop target
boolean isHoveringOverDelete = isHoveringOverDeleteDropTarget(
(int) mParentDownMotionX, (int) mParentDownMotionY);
setPageHoveringOverDeleteDropTarget(dragViewIndex, isHoveringOverDelete);
- if (DEBUG) Log.d(TAG, "leftBufferEdge: " + leftBufferEdge);
- if (DEBUG) Log.d(TAG, "rightBufferEdge: " + rightBufferEdge);
if (DEBUG) Log.d(TAG, "mLastMotionX: " + mLastMotionX);
if (DEBUG) Log.d(TAG, "mLastMotionY: " + mLastMotionY);
if (DEBUG) Log.d(TAG, "mParentDownMotionX: " + mParentDownMotionX);
if (DEBUG) Log.d(TAG, "mParentDownMotionY: " + mParentDownMotionY);
- float parentX = mParentDownMotionX;
- int pageIndexToSnapTo = -1;
- if (parentX < leftBufferEdge && dragViewIndex > 0) {
- pageIndexToSnapTo = dragViewIndex - 1;
- } else if (parentX > rightBufferEdge && dragViewIndex < getChildCount() - 1) {
- pageIndexToSnapTo = dragViewIndex + 1;
- }
-
- final int pageUnderPointIndex = pageIndexToSnapTo;
- if (pageUnderPointIndex > -1 && !isHoveringOverDelete) {
+ final int pageUnderPointIndex = getNearestHoverOverPageIndex();
+ if (pageUnderPointIndex > -1 && pageUnderPointIndex != indexOfChild(mDragView) &&
+ !isHoveringOverDelete) {
mTempVisiblePagesRange[0] = 0;
mTempVisiblePagesRange[1] = getPageCount() - 1;
- getReorderablePages(mTempVisiblePagesRange);
+ getOverviewModePages(mTempVisiblePagesRange);
if (mTempVisiblePagesRange[0] <= pageUnderPointIndex &&
pageUnderPointIndex <= mTempVisiblePagesRange[1] &&
pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) {
@@ -1637,10 +1674,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mSidePageHoverRunnable = new Runnable() {
@Override
public void run() {
- // Update the down scroll position to account for the fact that the
- // current page is moved
- mDownScrollX = getScrollForPage(pageUnderPointIndex);
-
// Setup the scroll to the correct page before we swap the views
snapToPage(pageUnderPointIndex);
@@ -1713,42 +1746,56 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING &&
Math.abs(velocityX) > mFlingThresholdVelocity;
- // In the case that the page is moved far to one direction and then is flung
- // in the opposite direction, we use a threshold to determine whether we should
- // just return to the starting page, or if we should skip one further.
- boolean returnToOriginalPage = false;
- if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD &&
- Math.signum(velocityX) != Math.signum(deltaX) && isFling) {
- returnToOriginalPage = true;
- }
+ if (!mFreeScroll) {
+ // In the case that the page is moved far to one direction and then is flung
+ // in the opposite direction, we use a threshold to determine whether we should
+ // just return to the starting page, or if we should skip one further.
+ boolean returnToOriginalPage = false;
+ if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD &&
+ Math.signum(velocityX) != Math.signum(deltaX) && isFling) {
+ returnToOriginalPage = true;
+ }
- int finalPage;
- // We give flings precedence over large moves, which is why we short-circuit our
- // test for a large move if a fling has been registered. That is, a large
- // move to the left and fling to the right will register as a fling to the right.
- final boolean isRtl = isLayoutRtl();
- boolean isDeltaXLeft = isRtl ? deltaX > 0 : deltaX < 0;
- boolean isVelocityXLeft = isRtl ? velocityX > 0 : velocityX < 0;
- if (((isSignificantMove && !isDeltaXLeft && !isFling) ||
- (isFling && !isVelocityXLeft)) && mCurrentPage > 0) {
- finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
- snapToPageWithVelocity(finalPage, velocityX);
- } else if (((isSignificantMove && isDeltaXLeft && !isFling) ||
- (isFling && isVelocityXLeft)) &&
- mCurrentPage < getChildCount() - 1) {
- finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
- snapToPageWithVelocity(finalPage, velocityX);
- } else {
- snapToDestination();
- } } else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
- // at this point we have not moved beyond the touch slop
- // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
- // we can just page
- int nextPage = Math.max(0, mCurrentPage - 1);
- if (nextPage != mCurrentPage) {
- snapToPage(nextPage);
+ int finalPage;
+ // We give flings precedence over large moves, which is why we short-circuit our
+ // test for a large move if a fling has been registered. That is, a large
+ // move to the left and fling to the right will register as a fling to the right.
+ final boolean isRtl = isLayoutRtl();
+ boolean isDeltaXLeft = isRtl ? deltaX > 0 : deltaX < 0;
+ boolean isVelocityXLeft = isRtl ? velocityX > 0 : velocityX < 0;
+ if (((isSignificantMove && !isDeltaXLeft && !isFling) ||
+ (isFling && !isVelocityXLeft)) && mCurrentPage > 0) {
+ finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
+ snapToPageWithVelocity(finalPage, velocityX);
+ } else if (((isSignificantMove && isDeltaXLeft && !isFling) ||
+ (isFling && isVelocityXLeft)) &&
+ mCurrentPage < getChildCount() - 1) {
+ finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
+ snapToPageWithVelocity(finalPage, velocityX);
+ } else {
+ snapToDestination();
+ } } else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
+ // at this point we have not moved beyond the touch slop
+ // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
+ // we can just page
+ int nextPage = Math.max(0, mCurrentPage - 1);
+ if (nextPage != mCurrentPage) {
+ snapToPage(nextPage);
+ } else {
+ snapToDestination();
+ }
} else {
- snapToDestination();
+ if (!mScroller.isFinished()) {
+ mScroller.abortAnimation();
+ }
+
+ float scaleX = getScaleX();
+ int vX = (int) (-velocityX * scaleX);
+ int initialScrollX = (int) (getScrollX() * scaleX);
+
+ mScroller.fling(initialScrollX,
+ getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0);
+ invalidate();
}
} else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
// at this point we have not moved beyond the touch slop
@@ -1803,6 +1850,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
+ releaseVelocityTracker();
break;
}
@@ -1819,7 +1867,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
endReordering();
mTouchState = TOUCH_STATE_REST;
mActivePointerId = INVALID_POINTER;
- mDownEventOnEdge = false;
}
protected void onUnhandledTap(MotionEvent ev) {}
@@ -1864,6 +1911,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
private void releaseVelocityTracker() {
if (mVelocityTracker != null) {
+ mVelocityTracker.clear();
mVelocityTracker.recycle();
mVelocityTracker = null;
}
@@ -2031,7 +2079,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
duration = Math.abs(delta);
}
- if (!mScroller.isFinished()) mScroller.abortAnimation();
+ if (!mScroller.isFinished()) {
+ mScroller.abortAnimation();
+ }
mScroller.startScroll(mUnboundedScrollX, 0, delta, 0, duration);
notifyPageSwitchListener();
@@ -2231,7 +2281,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
anim.setDuration(REORDERING_DROP_REPOSITION_DURATION);
anim.playTogether(
ObjectAnimator.ofFloat(mDragView, "translationX", 0f),
- ObjectAnimator.ofFloat(mDragView, "translationY", 0f));
+ ObjectAnimator.ofFloat(mDragView, "translationY", 0f),
+ ObjectAnimator.ofFloat(mDragView, "scaleX", 1f),
+ ObjectAnimator.ofFloat(mDragView, "scaleY", 1f));
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@@ -2242,59 +2294,11 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
}
- // "Zooms out" the PagedView to reveal more side pages
- protected boolean zoomOut() {
- if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
- mZoomInOutAnim.cancel();
- }
-
- if (!(getScaleX() < 1f || getScaleY() < 1f)) {
- mZoomInOutAnim = new AnimatorSet();
- mZoomInOutAnim.setDuration(REORDERING_ZOOM_IN_OUT_DURATION);
- mZoomInOutAnim.playTogether(
- ObjectAnimator.ofFloat(this, "scaleX", mMinScale),
- ObjectAnimator.ofFloat(this, "scaleY", mMinScale));
- mZoomInOutAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- // Show the delete drop target
- if (mDeleteDropTarget != null) {
- mDeleteDropTarget.setVisibility(View.VISIBLE);
- mDeleteDropTarget.animate().alpha(1f)
- .setDuration(REORDERING_DELETE_DROP_TARGET_FADE_DURATION)
- .setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- mDeleteDropTarget.setAlpha(0f);
- }
- });
- }
- }
- @Override
- public void onAnimationEnd(Animator animation) {
- // Update the visible pages
- invalidate();
- }
- });
- mZoomInOutAnim.start();
- return true;
- }
- return false;
- }
-
protected void onStartReordering() {
// Set the touch state to reordering (allows snapping to pages, dragging a child, etc.)
mTouchState = TOUCH_STATE_REORDERING;
mIsReordering = true;
- // Mark all the non-widget pages as invisible
- getReorderablePages(mTempVisiblePagesRange);
- for (int i = 0; i < getPageCount(); ++i) {
- if (i < mTempVisiblePagesRange[0] || i > mTempVisiblePagesRange[1]) {
- getPageAt(i).setAlpha(0f);
- }
- }
-
// We must invalidate to trigger a redraw to update the layers such that the drag view
// is always drawn on top
invalidate();
@@ -2312,32 +2316,24 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
protected void onEndReordering() {
mIsReordering = false;
-
- // Mark all the non-widget pages as visible again
- getReorderablePages(mTempVisiblePagesRange);
- for (int i = 0; i < getPageCount(); ++i) {
- if (i < mTempVisiblePagesRange[0] || i > mTempVisiblePagesRange[1]) {
- getPageAt(i).setAlpha(1f);
- }
- }
}
- public boolean startReordering() {
- int dragViewIndex = getPageNearestToCenterOfScreen();
+ public boolean startReordering(View v) {
+ int dragViewIndex = indexOfChild(v);//getPageNearestToCenterOfScreen();
mTempVisiblePagesRange[0] = 0;
mTempVisiblePagesRange[1] = getPageCount() - 1;
- getReorderablePages(mTempVisiblePagesRange);
+ getOverviewModePages(mTempVisiblePagesRange);
mReorderingStarted = true;
// Check if we are within the reordering range
if (mTempVisiblePagesRange[0] <= dragViewIndex &&
- dragViewIndex <= mTempVisiblePagesRange[1]) {
- if (zoomOut()) {
- // Find the drag view under the pointer
- mDragView = getChildAt(dragViewIndex);
-
- onStartReordering();
- }
+ dragViewIndex <= mTempVisiblePagesRange[1]) {
+ // Find the drag view under the pointer
+ mDragView = getChildAt(dragViewIndex);
+ mDragView.animate().scaleX(1.15f).scaleY(1.15f).setDuration(100).start();
+ mDragViewBaselineLeft = mDragView.getLeft();
+ disableFreeScroll(-1);
+ onStartReordering();
return true;
}
return false;
@@ -2367,7 +2363,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
if (!mDeferringForDelete) {
mPostReorderingPreZoomInRunnable = new Runnable() {
public void run() {
- zoomIn(onCompleteRunnable);
+ onCompleteRunnable.run();
+ enableFreeScroll();
};
};
@@ -2382,56 +2379,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
}
- // "Zooms in" the PagedView to highlight the current page
- protected boolean zoomIn(final Runnable onCompleteRunnable) {
- if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
- mZoomInOutAnim.cancel();
- }
- if (getScaleX() < 1f || getScaleY() < 1f) {
- mZoomInOutAnim = new AnimatorSet();
- mZoomInOutAnim.setDuration(REORDERING_ZOOM_IN_OUT_DURATION);
- mZoomInOutAnim.playTogether(
- ObjectAnimator.ofFloat(this, "scaleX", 1f),
- ObjectAnimator.ofFloat(this, "scaleY", 1f));
- mZoomInOutAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- // Hide the delete drop target
- if (mDeleteDropTarget != null) {
- mDeleteDropTarget.animate().alpha(0f)
- .setDuration(REORDERING_DELETE_DROP_TARGET_FADE_DURATION)
- .setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mDeleteDropTarget.setVisibility(View.GONE);
- }
- });
- }
- }
- @Override
- public void onAnimationCancel(Animator animation) {
- mDragView = null;
- }
- @Override
- public void onAnimationEnd(Animator animation) {
- mDragView = null;
- if (onCompleteRunnable != null) {
- onCompleteRunnable.run();
- }
- // Update the visible pages
- invalidate();
- }
- });
- mZoomInOutAnim.start();
- return true;
- } else {
- if (onCompleteRunnable != null) {
- onCompleteRunnable.run();
- }
- }
- return false;
- }
-
/*
* Flinging to delete - IN PROGRESS
*/
@@ -2507,7 +2454,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// in the layout)
// NOTE: We can make an assumption here because we have side-bound pages that we
// will always have pages to animate in from the left
- getReorderablePages(mTempVisiblePagesRange);
+ getOverviewModePages(mTempVisiblePagesRange);
boolean isLastWidgetPage = (mTempVisiblePagesRange[0] == mTempVisiblePagesRange[1]);
boolean slideFromLeft = (isLastWidgetPage ||
dragViewIndex > mTempVisiblePagesRange[0]);
@@ -2568,15 +2515,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
slideAnimations.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- final Runnable onCompleteRunnable = new Runnable() {
- @Override
- public void run() {
- mDeferringForDelete = false;
- onEndReordering();
- onRemoveViewAnimationCompleted();
- }
- };
- zoomIn(onCompleteRunnable);
+ mDeferringForDelete = false;
+ onEndReordering();
+ onRemoveViewAnimationCompleted();
}
});
slideAnimations.start();
@@ -2748,4 +2689,4 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
public boolean onHoverEvent(android.view.MotionEvent event) {
return true;
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 6989c9a..4e95f09 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -17,6 +17,8 @@
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;
@@ -87,6 +89,8 @@ public class Workspace extends SmoothPagedView
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;
+
// These animators are used to fade the children's outlines
private ObjectAnimator mChildrenOutlineFadeInAnimation;
private ObjectAnimator mChildrenOutlineFadeOutAnimation;
@@ -160,6 +164,7 @@ public class Workspace extends SmoothPagedView
private SpringLoadedDragController mSpringLoadedDragController;
private float mSpringLoadedShrinkFactor;
+ private float mOverviewModeShrinkFactor;
private static final int DEFAULT_CELL_COUNT_X = 4;
private static final int DEFAULT_CELL_COUNT_Y = 4;
@@ -167,7 +172,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 };
+ enum State { NORMAL, SPRING_LOADED, SMALL, OVERVIEW};
private State mState = State.NORMAL;
private boolean mIsSwitchingState = false;
@@ -331,13 +336,14 @@ public class Workspace extends SmoothPagedView
mSpringLoadedShrinkFactor =
res.getInteger(R.integer.config_workspaceSpringLoadShrinkPercentage) / 100.0f;
+ mOverviewModeShrinkFactor =
+ res.getInteger(R.integer.config_workspaceOverviewShrinkPercentage) / 100.0f;
mCameraDistance = res.getInteger(R.integer.config_cameraDistance);
// if the value is manually specified, use that instead
cellCountX = a.getInt(R.styleable.Workspace_cellCountX, cellCountX);
cellCountY = a.getInt(R.styleable.Workspace_cellCountY, cellCountY);
mDefaultPage = a.getInt(R.styleable.Workspace_defaultScreen, 1);
-
a.recycle();
setOnHierarchyChangeListener(this);
@@ -518,6 +524,7 @@ public class Workspace extends SmoothPagedView
mLauncher.getLayoutInflater().inflate(R.layout.workspace_screen, null);
newScreen.setOnLongClickListener(mLongClickListener);
+ newScreen.setOnClickListener(mLauncher);
mWorkspaceScreens.put(screenId, newScreen);
mScreenOrder.add(insertIndex, screenId);
addView(newScreen, insertIndex);
@@ -761,7 +768,8 @@ public class Workspace extends SmoothPagedView
*/
@Override
public boolean onTouch(View v, MotionEvent event) {
- return (isSmall() || !isFinishedSwitchingState());
+ return (isSmall() || !isFinishedSwitchingState())
+ || (!isSmall() && indexOfChild(v) != mCurrentPage);
}
public boolean isSwitchingState() {
@@ -810,11 +818,6 @@ public class Workspace extends SmoothPagedView
}
}
}
-
- if (mLauncher != null && mLauncher.onTouch(this, ev)) {
- return true;
- }
-
return super.onInterceptTouchEvent(ev);
}
@@ -843,7 +846,6 @@ public class Workspace extends SmoothPagedView
@Override
protected void determineScrollingStart(MotionEvent ev) {
- if (isSmall()) return;
if (!isFinishedSwitchingState()) return;
float deltaX = Math.abs(ev.getX() - mXDown);
@@ -1315,11 +1317,9 @@ public class Workspace extends SmoothPagedView
}
private void updateStateForCustomContent(int screenCenter) {
- if (hasCustomContent()) {
+ if (hasCustomContent() && !isSmall() && !isSwitchingState()) {
int index = mScreenOrder.indexOf(CUSTOM_CONTENT_SCREEN_ID);
-
int scrollDelta = getScrollForPage(index + 1) - getScrollX();
-
float progress = (1.0f * scrollDelta) /
(getScrollForPage(index + 1) - getScrollForPage(index));
progress = Math.max(0, progress);
@@ -1338,7 +1338,14 @@ public class Workspace extends SmoothPagedView
mLauncher.getHotseat().setAlpha(1 - progress);
}
if (getPageIndicator() != null) {
- getPageIndicator().setAlpha(1 - progress);
+ final float alpha = 1 - progress;
+ final View pi = getPageIndicator();
+ getPageIndicator().setAlpha(alpha);
+ if (alpha < ALPHA_CUTOFF_THRESHOLD && pi.getVisibility() != INVISIBLE) {
+ pi.setVisibility(INVISIBLE);
+ } else if (alpha > ALPHA_CUTOFF_THRESHOLD && pi.getVisibility() != VISIBLE) {
+ pi.setVisibility(VISIBLE);
+ }
}
}
}
@@ -1474,7 +1481,7 @@ public class Workspace extends SmoothPagedView
}
public boolean isSmall() {
- return mState == State.SMALL || mState == State.SPRING_LOADED;
+ return mState == State.SMALL || mState == State.SPRING_LOADED || mState == State.OVERVIEW;
}
void enableChildrenCache(int fromPage, int toPage) {
@@ -1508,9 +1515,8 @@ public class Workspace extends SmoothPagedView
}
}
-
private void updateChildrenLayersEnabled(boolean force) {
- boolean small = mState == State.SMALL || mIsSwitchingState;
+ boolean small = mState == State.SMALL || mState == State.OVERVIEW || mIsSwitchingState;
boolean enableChildrenLayers = force || small || mAnimatingViewIntoPlace || isPageMoving();
if (enableChildrenLayers != mChildrenLayersEnabled) {
@@ -1682,10 +1688,11 @@ public class Workspace extends SmoothPagedView
}
Animator getChangeStateAnimation(final State state, boolean animated) {
- return getChangeStateAnimation(state, animated, 0);
+ return getChangeStateAnimation(state, animated, 0, -1);
}
- void getReorderablePages(int[] range) {
+ @Override
+ protected void getOverviewModePages(int[] range) {
int count = mScreenOrder.size();
int start = -1;
@@ -1734,7 +1741,43 @@ public class Workspace extends SmoothPagedView
setLayoutTransition(mLayoutTransition);
}
- Animator getChangeStateAnimation(final State state, boolean animated, int delay) {
+ public boolean isInOverviewMode() {
+ return mState == State.OVERVIEW;
+ }
+
+ public void enterOverviewMode() {
+ enableOverviewMode(true, -1);
+ }
+
+ public void exitOverviewMode() {
+ exitOverviewMode(-1);
+ }
+
+ public void exitOverviewMode(int snapPage) {
+ enableOverviewMode(false, snapPage);
+ }
+
+ private void enableOverviewMode(boolean enable, int snapPage) {
+ State finalState = Workspace.State.OVERVIEW;
+ if (!enable) {
+ finalState = Workspace.State.NORMAL;
+ }
+
+ Animator workspaceAnim = getChangeStateAnimation(finalState, true, 0, snapPage);
+ workspaceAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator arg0) {
+ mIsSwitchingState = false;
+ }
+ @Override
+ public void onAnimationStart(Animator arg0) {
+ mIsSwitchingState = true;
+ }
+ });
+ workspaceAnim.start();
+ }
+
+ Animator getChangeStateAnimation(final State state, boolean animated, int delay, int snapPage) {
if (mState == state) {
return null;
}
@@ -1744,23 +1787,37 @@ public class Workspace extends SmoothPagedView
AnimatorSet anim = animated ? LauncherAnimUtils.createAnimatorSet() : null;
- // Stop any scrolling, move to the current page right away
- setCurrentPage(getNextPage());
-
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 oldStateIsOverview = (oldState == State.OVERVIEW);
mState = state;
final boolean stateIsNormal = (state == State.NORMAL);
final boolean stateIsSpringLoaded = (state == State.SPRING_LOADED);
final boolean stateIsSmall = (state == State.SMALL);
+ final boolean stateIsOverview = (state == State.OVERVIEW);
float finalBackgroundAlpha = stateIsSpringLoaded ? 1.0f : 0f;
+ float finalHotseatAndPageIndicatorAlpha = (stateIsOverview || stateIsSmall) ? 0f : 1f;
+ float finalOverviewPanelAlpha = stateIsOverview ? 1f : 0f;
+
boolean zoomIn = true;
mNewScale = 1.0f;
+ if (oldStateIsOverview) {
+ disableFreeScroll(snapPage);
+ } else if (stateIsOverview) {
+ enableFreeScroll();
+ }
+
if (state != State.NORMAL) {
- mNewScale = mSpringLoadedShrinkFactor - (stateIsSmall ? 0.1f : 0);
+ if (stateIsSpringLoaded) {
+ mNewScale = mSpringLoadedShrinkFactor;
+ } else if (stateIsOverview) {
+ mNewScale = mOverviewModeShrinkFactor;
+ } else if (stateIsSmall){
+ mNewScale = mOverviewModeShrinkFactor - 0.1f;
+ }
if (oldStateIsNormal && stateIsSmall) {
zoomIn = false;
updateChildrenLayersEnabled(false);
@@ -1844,7 +1901,24 @@ public class Workspace extends SmoothPagedView
}
}
}
+ ObjectAnimator hotseatAlpha = ObjectAnimator.ofFloat(mLauncher.getHotseat(), "alpha",
+ finalHotseatAndPageIndicatorAlpha);
+ ObjectAnimator pageIndicatorAlpha = ObjectAnimator.ofFloat(getPageIndicator(), "alpha",
+ finalHotseatAndPageIndicatorAlpha);
+ ObjectAnimator overviewPanelAlpha = ObjectAnimator.ofFloat(mLauncher.getOverviewPanel(),
+ "alpha", finalOverviewPanelAlpha);
+ overviewPanelAlpha.addUpdateListener(new AlphaUpdateListener(
+ mLauncher.getOverviewPanel()));
+ hotseatAlpha.addUpdateListener(new AlphaUpdateListener(mLauncher.getHotseat()));
+ pageIndicatorAlpha.addUpdateListener(new AlphaUpdateListener(getPageIndicator()));
+ anim.play(overviewPanelAlpha);
+ anim.play(hotseatAlpha);
+ anim.play(pageIndicatorAlpha);
anim.setStartDelay(delay);
+ } else {
+ mLauncher.getOverviewPanel().setAlpha(finalOverviewPanelAlpha);
+ mLauncher.getHotseat().setAlpha(finalHotseatAndPageIndicatorAlpha);
+ getPageIndicator().setAlpha(finalHotseatAndPageIndicatorAlpha);
}
if (stateIsSpringLoaded) {
@@ -1860,6 +1934,24 @@ public class Workspace extends SmoothPagedView
return anim;
}
+ class AlphaUpdateListener implements AnimatorUpdateListener {
+ View view;
+ public AlphaUpdateListener(View v) {
+ view = v;
+ }
+
+ @Override
+ public void onAnimationUpdate(ValueAnimator arg0) {
+ if (view.getAlpha() < ALPHA_CUTOFF_THRESHOLD && view.getVisibility() != INVISIBLE) {
+ view.setVisibility(INVISIBLE);
+ } else if (view.getAlpha() > ALPHA_CUTOFF_THRESHOLD
+ && view.getVisibility() != VISIBLE) {
+ view.setVisibility(VISIBLE);
+ }
+ }
+
+ }
+
@Override
public void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace) {
mIsSwitchingState = true;