All Apps physics polish.

With this change, the springs will now animate if your finger
is on the RecyclerView while you hit the top/bottom.

This covers the case when the user has few apps (ie. the
RecyclerView does not scroll very much).

Bug: 64041310

Change-Id: Ia72aea05d62a6fb896fdb7df379d6c7abd188d6d
This commit is contained in:
Jon Miranda 2017-07-25 14:13:32 -07:00 committed by Jonathan Miranda
parent df4aaca594
commit 2d5e0e067c
2 changed files with 23 additions and 32 deletions

View File

@ -21,7 +21,6 @@ import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.InsetDrawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Selection;
import android.text.SpannableStringBuilder;
import android.util.AttributeSet;
@ -227,7 +226,6 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
mAppsRecyclerView.setHasFixedSize(true);
if (FeatureFlags.LAUNCHER3_PHYSICS) {
mAppsRecyclerView.setSpringAnimationHandler(mSpringAnimationHandler);
mAppsRecyclerView.addOnScrollListener(new SpringMotionOnScrollListener());
}
mSearchContainer = findViewById(R.id.search_container_all_apps);
@ -403,33 +401,4 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
public SpringAnimationHandler getSpringAnimationHandler() {
return mSpringAnimationHandler;
}
public class SpringMotionOnScrollListener extends RecyclerView.OnScrollListener {
private int mScrollState = RecyclerView.SCROLL_STATE_IDLE;
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (mScrollState == RecyclerView.SCROLL_STATE_DRAGGING || (dx == 0 && dy == 0)) {
if (mSpringAnimationHandler.isRunning()){
mSpringAnimationHandler.skipToEnd();
}
return;
}
// We only start the spring animation when we fling and hit the top/bottom, to ensure
// that all of the animations start at the same time.
if (dy < 0 && !mAppsRecyclerView.canScrollVertically(-1)) {
mSpringAnimationHandler.animateToFinalPosition(0, 1);
} else if (dy > 0 && !mAppsRecyclerView.canScrollVertically(1)) {
mSpringAnimationHandler.animateToFinalPosition(0, -1);
}
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
mScrollState = newState;
}
}
}

View File

@ -103,7 +103,10 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine
}
public void setSpringAnimationHandler(SpringAnimationHandler springAnimationHandler) {
mSpringAnimationHandler = springAnimationHandler;
if (FeatureFlags.LAUNCHER3_PHYSICS) {
mSpringAnimationHandler = springAnimationHandler;
addOnScrollListener(new SpringMotionOnScrollListener());
}
}
@Override
@ -485,6 +488,25 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine
y + mEmptySearchBackground.getIntrinsicHeight());
}
private class SpringMotionOnScrollListener extends RecyclerView.OnScrollListener {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (mOverScrollHelper.isInOverScroll()) {
// OverScroll will handle animating the springs.
return;
}
// We only start the spring animation when we hit the top/bottom, to ensure
// that all of the animations start at the same time.
if (dy < 0 && !canScrollVertically(-1)) {
mSpringAnimationHandler.animateToFinalPosition(0, 1);
} else if (dy > 0 && !canScrollVertically(1)) {
mSpringAnimationHandler.animateToFinalPosition(0, -1);
}
}
}
private class OverScrollHelper implements VerticalPullDetector.Listener {
private static final float MAX_RELEASE_VELOCITY = 5000; // px / s