Loading quickstep/src/com/android/quickstep/RecentsView.java +44 −0 Original line number Diff line number Diff line Loading @@ -16,10 +16,12 @@ package com.android.quickstep; import android.animation.TimeInterpolator; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; Loading @@ -41,6 +43,12 @@ import java.util.ArrayList; */ public class RecentsView extends PagedView { /** Designates how "curvy" the carousel is from 0 to 1, where 0 is a straight line. */ private static final float CURVE_FACTOR = 0.25f; /** A circular curve of x from 0 to 1, where 0 is the center of the screen and 1 is the edge. */ private static final TimeInterpolator CURVE_INTERPOLATOR = x -> (float) (1 - Math.sqrt(1 - Math.pow(x, 2))); private boolean mOverviewStateEnabled; private boolean mTaskStackListenerRegistered; Loading Loading @@ -69,6 +77,7 @@ public class RecentsView extends PagedView { super(context, attrs, defStyleAttr); setWillNotDraw(false); setPageSpacing((int) getResources().getDimension(R.dimen.recents_page_spacing)); enableFreeScroll(true); } @Override Loading Loading @@ -170,4 +179,39 @@ public class RecentsView extends PagedView { padding.left = padding.right = (int) ((profile.availableWidthPx - overviewWidth) / 2); return padding; } @Override public void scrollTo(int x, int y) { super.scrollTo(x, y); updateCurveProperties(); } /** * Scales and adjusts translation of adjacent pages as if on a curved carousel. */ private void updateCurveProperties() { if (getPageCount() == 0 || getPageAt(0).getMeasuredWidth() == 0) { return; } final int halfScreenWidth = getMeasuredWidth() / 2; final int screenCenter = halfScreenWidth + getScrollX(); final int pageSpacing = getResources().getDimensionPixelSize(R.dimen.recents_page_spacing); final int pageCount = getPageCount(); for (int i = 0; i < pageCount; i++) { View page = getPageAt(i); int pageWidth = page.getMeasuredWidth(); int halfPageWidth = pageWidth / 2; int pageCenter = page.getLeft() + halfPageWidth; float distanceFromScreenCenter = Math.abs(pageCenter - screenCenter); float distanceToReachEdge = halfScreenWidth + halfPageWidth + pageSpacing; float linearInterpolation = Math.min(1, distanceFromScreenCenter / distanceToReachEdge); float curveInterpolation = CURVE_INTERPOLATOR.getInterpolation(linearInterpolation); float scale = 1 - curveInterpolation * CURVE_FACTOR; page.setScaleX(scale); page.setScaleY(scale); // Make sure the biggest card (i.e. the one in front) shows on top of the adjacent ones. page.setTranslationZ(scale); page.setTranslationX((screenCenter - pageCenter) * curveInterpolation * CURVE_FACTOR); } } } src/com/android/launcher3/PagedView.java +22 −2 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.view.InputDevice; import android.view.KeyEvent; Loading Loading @@ -87,6 +86,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc public static final int INVALID_RESTORE_PAGE = -1001; private boolean mFreeScroll = false; private boolean mSettleOnPageInFreeScroll = false; protected int mFlingThresholdVelocity; protected int mMinFlingVelocity; Loading Loading @@ -1170,7 +1170,12 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc * return true if freescroll has been enabled, false otherwise */ protected void enableFreeScroll() { enableFreeScroll(false); } protected void enableFreeScroll(boolean settleOnPageInFreeScroll) { setEnableFreeScroll(true); mSettleOnPageInFreeScroll = settleOnPageInFreeScroll; } protected void disableFreeScroll() { Loading Loading @@ -1414,7 +1419,22 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc mScroller.setInterpolator(mDefaultInterpolator); mScroller.fling(initialScrollX, getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0); mNextPage = getPageNearestToCenterOfScreen((int) (mScroller.getFinalX() / scaleX)); int unscaledScrollX = (int) (mScroller.getFinalX() / scaleX); mNextPage = getPageNearestToCenterOfScreen(unscaledScrollX); int firstPageScroll = getScrollForPage(!mIsRtl ? 0 : getPageCount() - 1); int lastPageScroll = getScrollForPage(!mIsRtl ? getPageCount() - 1 : 0); if (mSettleOnPageInFreeScroll && unscaledScrollX > firstPageScroll && unscaledScrollX < lastPageScroll) { // Make sure we land directly on a page. If flinging past one of the ends, // don't change the velocity as it will get stopped at the end anyway. mScroller.setFinalX((int) (getScrollForPage(mNextPage) * getScaleX())); // Ensure the scroll/snap doesn't happen too fast; int extraScrollDuration = OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION - mScroller.getDuration(); if (extraScrollDuration > 0) { mScroller.extendDuration(extraScrollDuration); } } invalidate(); } onScrollInteractionEnd(); Loading Loading
quickstep/src/com/android/quickstep/RecentsView.java +44 −0 Original line number Diff line number Diff line Loading @@ -16,10 +16,12 @@ package com.android.quickstep; import android.animation.TimeInterpolator; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; Loading @@ -41,6 +43,12 @@ import java.util.ArrayList; */ public class RecentsView extends PagedView { /** Designates how "curvy" the carousel is from 0 to 1, where 0 is a straight line. */ private static final float CURVE_FACTOR = 0.25f; /** A circular curve of x from 0 to 1, where 0 is the center of the screen and 1 is the edge. */ private static final TimeInterpolator CURVE_INTERPOLATOR = x -> (float) (1 - Math.sqrt(1 - Math.pow(x, 2))); private boolean mOverviewStateEnabled; private boolean mTaskStackListenerRegistered; Loading Loading @@ -69,6 +77,7 @@ public class RecentsView extends PagedView { super(context, attrs, defStyleAttr); setWillNotDraw(false); setPageSpacing((int) getResources().getDimension(R.dimen.recents_page_spacing)); enableFreeScroll(true); } @Override Loading Loading @@ -170,4 +179,39 @@ public class RecentsView extends PagedView { padding.left = padding.right = (int) ((profile.availableWidthPx - overviewWidth) / 2); return padding; } @Override public void scrollTo(int x, int y) { super.scrollTo(x, y); updateCurveProperties(); } /** * Scales and adjusts translation of adjacent pages as if on a curved carousel. */ private void updateCurveProperties() { if (getPageCount() == 0 || getPageAt(0).getMeasuredWidth() == 0) { return; } final int halfScreenWidth = getMeasuredWidth() / 2; final int screenCenter = halfScreenWidth + getScrollX(); final int pageSpacing = getResources().getDimensionPixelSize(R.dimen.recents_page_spacing); final int pageCount = getPageCount(); for (int i = 0; i < pageCount; i++) { View page = getPageAt(i); int pageWidth = page.getMeasuredWidth(); int halfPageWidth = pageWidth / 2; int pageCenter = page.getLeft() + halfPageWidth; float distanceFromScreenCenter = Math.abs(pageCenter - screenCenter); float distanceToReachEdge = halfScreenWidth + halfPageWidth + pageSpacing; float linearInterpolation = Math.min(1, distanceFromScreenCenter / distanceToReachEdge); float curveInterpolation = CURVE_INTERPOLATOR.getInterpolation(linearInterpolation); float scale = 1 - curveInterpolation * CURVE_FACTOR; page.setScaleX(scale); page.setScaleY(scale); // Make sure the biggest card (i.e. the one in front) shows on top of the adjacent ones. page.setTranslationZ(scale); page.setTranslationX((screenCenter - pageCenter) * curveInterpolation * CURVE_FACTOR); } } }
src/com/android/launcher3/PagedView.java +22 −2 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.view.InputDevice; import android.view.KeyEvent; Loading Loading @@ -87,6 +86,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc public static final int INVALID_RESTORE_PAGE = -1001; private boolean mFreeScroll = false; private boolean mSettleOnPageInFreeScroll = false; protected int mFlingThresholdVelocity; protected int mMinFlingVelocity; Loading Loading @@ -1170,7 +1170,12 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc * return true if freescroll has been enabled, false otherwise */ protected void enableFreeScroll() { enableFreeScroll(false); } protected void enableFreeScroll(boolean settleOnPageInFreeScroll) { setEnableFreeScroll(true); mSettleOnPageInFreeScroll = settleOnPageInFreeScroll; } protected void disableFreeScroll() { Loading Loading @@ -1414,7 +1419,22 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc mScroller.setInterpolator(mDefaultInterpolator); mScroller.fling(initialScrollX, getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0); mNextPage = getPageNearestToCenterOfScreen((int) (mScroller.getFinalX() / scaleX)); int unscaledScrollX = (int) (mScroller.getFinalX() / scaleX); mNextPage = getPageNearestToCenterOfScreen(unscaledScrollX); int firstPageScroll = getScrollForPage(!mIsRtl ? 0 : getPageCount() - 1); int lastPageScroll = getScrollForPage(!mIsRtl ? getPageCount() - 1 : 0); if (mSettleOnPageInFreeScroll && unscaledScrollX > firstPageScroll && unscaledScrollX < lastPageScroll) { // Make sure we land directly on a page. If flinging past one of the ends, // don't change the velocity as it will get stopped at the end anyway. mScroller.setFinalX((int) (getScrollForPage(mNextPage) * getScaleX())); // Ensure the scroll/snap doesn't happen too fast; int extraScrollDuration = OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION - mScroller.getDuration(); if (extraScrollDuration > 0) { mScroller.extendDuration(extraScrollDuration); } } invalidate(); } onScrollInteractionEnd(); Loading