From c86df470ab360a6e3f7edfd4b9cadcc5c31734f8 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 25 Feb 2016 09:19:38 -0800 Subject: [PATCH] Adding overlay interaction support > Sending unboundX to the overlay which is the total untranslated X and not just deltaX from last frame > Handling overlay callback and translating workspace accordingly Change-Id: I3bd8d9efac738e9ce131758f0e5ff1b9c1d6a8fc --- src/com/android/launcher3/Launcher.java | 22 +++-- .../android/launcher3/LauncherCallbacks.java | 2 + src/com/android/launcher3/PagedView.java | 14 +-- src/com/android/launcher3/Workspace.java | 89 ++++++++++++++++--- .../launcher3/testing/LauncherExtension.java | 8 ++ 5 files changed, 109 insertions(+), 26 deletions(-) diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index a5c6720852..68b0dff0de 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -1107,12 +1107,7 @@ public class Launcher extends Activity * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost * screen (or in the case of RTL, the rightmost screen). */ - public void onScrollChange(int progress, boolean rtl); - - /** - * Screen has stopped scrolling - */ - public void onScrollSettled(); + public void onScrollChange(float progress, boolean rtl); /** * Called when the launcher is ready to use the overlay @@ -1134,11 +1129,16 @@ public class Launcher extends Activity } public interface LauncherOverlayCallbacks { - + public void onScrollChanged(float progress); } class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks { + public void onScrollChanged(float progress) { + if (mWorkspace != null) { + mWorkspace.onOverlayScrollChanged(progress); + } + } } protected boolean hasSettings() { @@ -1631,6 +1631,10 @@ public class Launcher extends Activity FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView()); mAttached = true; mVisible = true; + + if (mLauncherCallbacks != null) { + mLauncherCallbacks.onAttachedToWindow(); + } } @Override @@ -1643,6 +1647,10 @@ public class Launcher extends Activity mAttached = false; } updateAutoAdvanceState(); + + if (mLauncherCallbacks != null) { + mLauncherCallbacks.onDetachedFromWindow(); + } } public void onWindowVisibilityChanged(int visibility) { diff --git a/src/com/android/launcher3/LauncherCallbacks.java b/src/com/android/launcher3/LauncherCallbacks.java index 591bd9206b..0be45c389e 100644 --- a/src/com/android/launcher3/LauncherCallbacks.java +++ b/src/com/android/launcher3/LauncherCallbacks.java @@ -43,6 +43,8 @@ public interface LauncherCallbacks { public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults); public void onWindowFocusChanged(boolean hasFocus); + public void onAttachedToWindow(); + public void onDetachedFromWindow(); public boolean onPrepareOptionsMenu(Menu menu); public void dump(String prefix, FileDescriptor fd, PrintWriter w, String[] args); public void onHomeIntent(); diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index c826c5fcda..b3a714b81f 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -100,7 +100,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc @ViewDebug.ExportedProperty(category = "launcher") protected int mNextPage = INVALID_PAGE; - private int mMaxScrollX; + protected int mMaxScrollX; protected LauncherScroller mScroller; private Interpolator mDefaultInterpolator; private VelocityTracker mVelocityTracker; @@ -542,9 +542,13 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc super.setOnLongClickListener(l); } + protected int getUnboundedScrollX() { + return getScrollX(); + } + @Override public void scrollBy(int x, int y) { - scrollTo(getScrollX() + x, getScrollY() + y); + scrollTo(getUnboundedScrollX() + x, getScrollY() + y); } @Override @@ -1987,7 +1991,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc int halfScreenSize = getViewportWidth() / 2; final int newX = getScrollForPage(whichPage); - int delta = newX - getScrollX(); + int delta = newX - getUnboundedScrollX(); int duration = 0; if (Math.abs(velocity) < mMinFlingVelocity) { @@ -2037,7 +2041,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc whichPage = validateNewPage(whichPage); int newX = getScrollForPage(whichPage); - final int delta = newX - getScrollX(); + final int delta = newX - getUnboundedScrollX(); snapToPage(whichPage, delta, duration, immediate, interpolator); } @@ -2069,7 +2073,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc mScroller.setInterpolator(mDefaultInterpolator); } - mScroller.startScroll(getScrollX(), 0, delta, 0, duration); + mScroller.startScroll(getUnboundedScrollX(), 0, delta, 0, duration); updatePageIndicator(); diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 840f9f2fac..e983e79762 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -31,6 +31,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Point; import android.graphics.PointF; @@ -51,6 +52,9 @@ import android.view.View; import android.view.ViewDebug; import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.DecelerateInterpolator; +import android.view.animation.Interpolator; import android.widget.TextView; import com.android.launcher3.folder.Folder; @@ -264,9 +268,12 @@ public class Workspace extends PagedView LauncherOverlay mLauncherOverlay; boolean mScrollInteractionBegan; boolean mStartedSendingScrollEvents; - boolean mShouldSendPageSettled; - int mLastOverlaySroll = 0; + float mLastOverlaySroll = 0; + // Total over scrollX in the overlay direction. + private int mUnboundedScrollX; private boolean mForceDrawAdjacentPages = false; + // Total over scrollX in the overlay direction. + private float mOverlayTranslation; // Handles workspace state transitions private WorkspaceStateTransitionAnimation mStateTransitionAnimation; @@ -1202,11 +1209,6 @@ public class Workspace extends PagedView stripEmptyScreens(); mStripScreensOnPageStopMoving = false; } - - if (mShouldSendPageSettled) { - mLauncherOverlay.onScrollSettled(); - mShouldSendPageSettled = false; - } } protected void onScrollInteractionBegin() { @@ -1225,6 +1227,27 @@ public class Workspace extends PagedView public void setLauncherOverlay(LauncherOverlay overlay) { mLauncherOverlay = overlay; + // A new overlay has been set. Reset event tracking + mStartedSendingScrollEvents = false; + onOverlayScrollChanged(0); + } + + @Override + protected int getUnboundedScrollX() { + if (mLauncherOverlay != null) { + if ((mIsRtl && mUnboundedScrollX > mMaxScrollX) || + (!mIsRtl && mUnboundedScrollX < 0)) { + return mUnboundedScrollX; + } + } + + return super.getUnboundedScrollX(); + } + + @Override + public void scrollTo(int x, int y) { + mUnboundedScrollX = x; + super.scrollTo(x, y); } @Override @@ -1242,15 +1265,10 @@ public class Workspace extends PagedView if (!mStartedSendingScrollEvents && mScrollInteractionBegan) { mStartedSendingScrollEvents = true; mLauncherOverlay.onScrollInteractionBegin(); - mShouldSendPageSettled = true; } - int screenSize = getViewportWidth(); - float f = (amount / screenSize); - int progress = (int) Math.abs((f * 100)); - - mLastOverlaySroll = progress; - mLauncherOverlay.onScrollChange(progress, mIsRtl); + mLastOverlaySroll = Math.abs(amount / getViewportWidth()); + mLauncherOverlay.onScrollChange(mLastOverlaySroll, mIsRtl); } else if (shouldOverScroll) { dampedOverScroll(amount); } @@ -1260,6 +1278,49 @@ public class Workspace extends PagedView } } + private final Interpolator mAlphaInterpolator = new DecelerateInterpolator(3f); + + /** + * The overlay scroll is being controlled locally, just update our overlay effect + */ + public void onOverlayScrollChanged(float scroll) { + float offset = 0f; + float slip = 0f; + + scroll = Math.max(scroll - offset, 0); + scroll = Math.min(1, scroll / (1 - offset)); + + float alpha = 1 - mAlphaInterpolator.getInterpolation(scroll); + float transX = mLauncher.getDragLayer().getMeasuredWidth() * scroll; + transX *= 1 - slip; + + if (mIsRtl) { + transX = -transX; + } + + // TODO(adamcohen): figure out a final effect here. We may need to recommend + // different effects based on device performance. On at least one relatively high-end + // device I've tried, translating the launcher causes things to get quite laggy. + setTranslationAndAlpha(mLauncher.getSearchDropTargetBar(), transX, alpha); + setTranslationAndAlpha(getPageIndicator(), transX, alpha); + setTranslationAndAlpha(getChildAt(getCurrentPage()), transX, alpha); + setTranslationAndAlpha(mLauncher.getHotseat(), transX, alpha); + + // When the animation finishes, reset all pages, just in case we missed a page. + if (transX == 0) { + for (int i = getChildCount() - 1; i >= 0; i--) { + setTranslationAndAlpha(getChildAt(i), 0, alpha); + } + } + } + + private void setTranslationAndAlpha(View v, float transX, float alpha) { + if (v != null) { + v.setTranslationX(transX); + v.setAlpha(alpha); + } + } + @Override protected void getEdgeVerticalPostion(int[] pos) { View child = getChildAt(getPageCount() - 1); diff --git a/src/com/android/launcher3/testing/LauncherExtension.java b/src/com/android/launcher3/testing/LauncherExtension.java index 279be70372..475762f74b 100644 --- a/src/com/android/launcher3/testing/LauncherExtension.java +++ b/src/com/android/launcher3/testing/LauncherExtension.java @@ -293,5 +293,13 @@ public class LauncherExtension extends Launcher { public void setLauncherSearchCallback(Object callbacks) { // Do nothing } + + @Override + public void onAttachedToWindow() { + } + + @Override + public void onDetachedFromWindow() { + }; } }