Fix adjacent task offset distance

Instead of calculating an overall distance for tasks to translate
based on RecentsView width, calculate the distance for the tasks
to the left and right of the midpoint based on how far the first
adjacent tasks in those directions are from being offscreen.

Changes made to make "distance to offscreen" calculations possible:
- Update TaskView curve scale to reach final scale as soon as it is
  completely offscreen. Before, it would reach its final scale just
  shy of that point (calculations were off).
- As we update RecentsView scale, calculate how much the new scale
  will push out tasks that are just offscreen.
- With both above, we can calculate the scale and position of a
  TaskView such that it is just offscreen, and interpolate
  between its current position and that position.

Tests:
- Task comes in immediately when quick switching from home, and
  doesn't shift as you swipe directly upwards.
- When swiping far up from an app, tasks come in from all the way
  offscreen, and cover distance appropriately (e.g. if you're
  scrolled a bit to the right when you pause, the left adjacent
  app will move faster to cover the farther distance).
- Task modalness: entering Select mode now animates adjacent tasks
  at the same rate as the scaling up, because they move only the
  distance needed to get offscreen (before they moved way too far
  and thus seemed to be much faster than the rest of the animation).

Bug: 149934536
Change-Id: Ie3fffe0e5c304cb16e7637f058f5ce72cee40aeb
This commit is contained in:
Tony Wickham
2020-07-07 19:25:25 -07:00
parent eb268055e1
commit 7383d4e6d2
11 changed files with 146 additions and 35 deletions

View File

@@ -1448,11 +1448,8 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
int minDistanceFromScreenCenterIndex = -1;
final int childCount = getChildCount();
for (int i = 0; i < childCount; ++i) {
View layout = getPageAt(i);
int childSize = mOrientationHandler.getMeasuredSize(layout);
int halfChildSize = (childSize / 2);
int childCenter = getChildOffset(i) + halfChildSize;
int distanceFromScreenCenter = Math.abs(childCenter - screenCenter);
int distanceFromScreenCenter = Math.abs(
getDisplacementFromScreenCenter(i, screenCenter));
if (distanceFromScreenCenter < minDistanceFromScreenCenter) {
minDistanceFromScreenCenter = distanceFromScreenCenter;
minDistanceFromScreenCenterIndex = i;
@@ -1461,6 +1458,20 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
return minDistanceFromScreenCenterIndex;
}
private int getDisplacementFromScreenCenter(int childIndex, int screenCenter) {
View layout = getPageAt(childIndex);
int childSize = mOrientationHandler.getMeasuredSize(layout);
int halfChildSize = (childSize / 2);
int childCenter = getChildOffset(childIndex) + halfChildSize;
return childCenter - screenCenter;
}
protected int getDisplacementFromScreenCenter(int childIndex) {
int pageOrientationSize = mOrientationHandler.getMeasuredSize(this);
int screenCenter = mOrientationHandler.getPrimaryScroll(this) + (pageOrientationSize / 2);
return getDisplacementFromScreenCenter(childIndex, screenCenter);
}
protected void snapToDestination() {
snapToPage(getPageNearestToCenterOfScreen(), getPageSnapDuration());
}