mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 03:08:19 +00:00
Add translation component to swipe up resistance
Now recents view follows your finger all the way to the top of the screen. Specifically, your finger tracks the bottom of the window until resistance starts (when RecentsView is at 75% scale), then we add translation to compensate for the slower rate of scaling down, such that your finger slips to the top of the window by the time it reaches the top of the screen. Also reset this translation back to 0 in the state handlers. Bug: 149934536 Fixes: 158701272 Change-Id: Iaee58da758d422f0173c29d002f5c451ce0c1809
This commit is contained in:
@@ -101,7 +101,8 @@ public abstract class SwipeUpAnimationLogic {
|
||||
AnimatorPlaybackController normalController = pa.createPlaybackController();
|
||||
mWindowTransitionController = AnimatorControllerWithResistance.createForRecents(
|
||||
normalController, mContext, mTaskViewSimulator.getOrientationState(),
|
||||
mDp, mTaskViewSimulator.recentsViewScale, AnimatedFloat.VALUE);
|
||||
mDp, mTaskViewSimulator.recentsViewScale, AnimatedFloat.VALUE,
|
||||
mTaskViewSimulator.recentsViewSecondaryTranslation, AnimatedFloat.VALUE);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
|
||||
@@ -19,6 +19,7 @@ import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MODAL;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
||||
@@ -26,6 +27,7 @@ import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
|
||||
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_MODALNESS;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
|
||||
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.anim.PropertySetter;
|
||||
@@ -86,6 +88,8 @@ public class FallbackRecentsStateController implements StateHandler<RecentsState
|
||||
config.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR));
|
||||
setter.setFloat(mRecentsView, ADJACENT_PAGE_OFFSET, scaleAndOffset[1],
|
||||
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_X, LINEAR));
|
||||
setter.setFloat(mRecentsView, TASK_SECONDARY_TRANSLATION, 0f,
|
||||
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
|
||||
|
||||
setter.setFloat(mRecentsView, TASK_MODALNESS, state.getOverviewModalness(),
|
||||
config.getInterpolator(ANIM_OVERVIEW_MODAL, LINEAR));
|
||||
|
||||
@@ -90,7 +90,6 @@ public class RecentsState implements BaseState<RecentsState> {
|
||||
return new float[] { NO_SCALE, NO_OFFSET };
|
||||
}
|
||||
|
||||
|
||||
private static class ModalState extends RecentsState {
|
||||
|
||||
public ModalState(int id, int flags) {
|
||||
|
||||
@@ -90,6 +90,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
// RecentsView properties
|
||||
public final AnimatedFloat recentsViewScale = new AnimatedFloat();
|
||||
public final AnimatedFloat fullScreenProgress = new AnimatedFloat();
|
||||
public final AnimatedFloat recentsViewSecondaryTranslation = new AnimatedFloat();
|
||||
private final ScrollState mScrollState = new ScrollState();
|
||||
|
||||
// Cached calculations
|
||||
@@ -274,8 +275,10 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
mOrientationState.getOrientationHandler().set(
|
||||
mMatrix, MATRIX_POST_TRANSLATE, mScrollState.scroll);
|
||||
|
||||
// Apply recensView matrix
|
||||
// Apply RecentsView matrix
|
||||
mMatrix.postScale(recentsViewScale.value, recentsViewScale.value, mPivot.x, mPivot.y);
|
||||
mOrientationState.getOrientationHandler().setSecondary(mMatrix, MATRIX_POST_TRANSLATE,
|
||||
recentsViewSecondaryTranslation.value);
|
||||
applyWindowToHomeRotation(mMatrix);
|
||||
|
||||
// Crop rect is the inverse of thumbnail matrix
|
||||
|
||||
@@ -210,6 +210,19 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
|
||||
}
|
||||
};
|
||||
|
||||
public static final FloatProperty<RecentsView> TASK_SECONDARY_TRANSLATION =
|
||||
new FloatProperty<RecentsView>("taskSecondaryTranslation") {
|
||||
@Override
|
||||
public void setValue(RecentsView recentsView, float v) {
|
||||
recentsView.setTaskViewsSecondaryTranslation(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(RecentsView recentsView) {
|
||||
return recentsView.mTaskViewsSecondaryTranslation;
|
||||
}
|
||||
};
|
||||
|
||||
/** Same as normal SCALE_PROPERTY, but also updates page offsets that depend on this scale. */
|
||||
public static final FloatProperty<RecentsView> RECENTS_SCALE_PROPERTY =
|
||||
new FloatProperty<RecentsView>("recentsScale") {
|
||||
@@ -219,6 +232,7 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
|
||||
view.setScaleY(scale);
|
||||
view.mLastComputedTaskPushOutDistance = null;
|
||||
view.updatePageOffsets();
|
||||
view.setTaskViewsSecondaryTranslation(view.mTaskViewsSecondaryTranslation);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -269,6 +283,7 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
|
||||
protected boolean mFreezeViewVisibility;
|
||||
|
||||
private float mAdjacentPageOffset = 0;
|
||||
private float mTaskViewsSecondaryTranslation = 0;
|
||||
|
||||
/**
|
||||
* TODO: Call reloadIdNeeded in onTaskStackChanged.
|
||||
@@ -1391,7 +1406,7 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
|
||||
FloatProperty<View> secondaryViewTranslate =
|
||||
mOrientationHandler.getSecondaryViewTranslate();
|
||||
int secondaryTaskDimension = mOrientationHandler.getSecondaryDimension(taskView);
|
||||
int verticalFactor = mOrientationHandler.getTaskDismissDirectionFactor();
|
||||
int verticalFactor = mOrientationHandler.getSecondaryTranslationDirectionFactor();
|
||||
|
||||
ResourceProvider rp = DynamicResource.provider(mActivity);
|
||||
SpringProperty sp = new SpringProperty(SpringProperty.FLAG_CAN_SPRING_ON_START)
|
||||
@@ -1908,6 +1923,14 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
|
||||
return distanceToOffscreen * offsetProgress;
|
||||
}
|
||||
|
||||
private void setTaskViewsSecondaryTranslation(float translation) {
|
||||
mTaskViewsSecondaryTranslation = translation;
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
TaskView task = getTaskViewAt(i);
|
||||
mOrientationHandler.getSecondaryViewTranslate().set(task, translation / getScaleY());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Do not assume motion across X axis for adjacent page
|
||||
*/
|
||||
|
||||
@@ -24,11 +24,13 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MO
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCRIM_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
|
||||
|
||||
import android.util.FloatProperty;
|
||||
|
||||
@@ -63,6 +65,7 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
|
||||
float[] scaleAndOffset = state.getOverviewScaleAndOffset(mLauncher);
|
||||
RECENTS_SCALE_PROPERTY.set(mRecentsView, scaleAndOffset[0]);
|
||||
ADJACENT_PAGE_OFFSET.set(mRecentsView, scaleAndOffset[1]);
|
||||
TASK_SECONDARY_TRANSLATION.set(mRecentsView, 0f);
|
||||
|
||||
getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0);
|
||||
OverviewScrim scrim = mLauncher.getDragLayer().getOverviewScrim();
|
||||
@@ -97,6 +100,8 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
|
||||
config.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR));
|
||||
setter.setFloat(mRecentsView, ADJACENT_PAGE_OFFSET, scaleAndOffset[1],
|
||||
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_X, LINEAR));
|
||||
setter.setFloat(mRecentsView, TASK_SECONDARY_TRANSLATION, 0f,
|
||||
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
|
||||
|
||||
setter.setFloat(mRecentsView, getContentAlphaProperty(), toState.overviewUi ? 1 : 0,
|
||||
config.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
|
||||
|
||||
@@ -28,6 +28,7 @@ import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_REC
|
||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
|
||||
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.annotation.TargetApi;
|
||||
@@ -357,7 +358,8 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
AnimatorControllerWithResistance controllerWithResistance =
|
||||
AnimatorControllerWithResistance.createForRecents(controller, mActivity,
|
||||
recentsView.getPagedViewOrientedState(), mActivity.getDeviceProfile(),
|
||||
recentsView, RECENTS_SCALE_PROPERTY);
|
||||
recentsView, RECENTS_SCALE_PROPERTY, recentsView,
|
||||
TASK_SECONDARY_TRANSLATION);
|
||||
mCallback.accept(controllerWithResistance);
|
||||
|
||||
// Creating the activity controller animation sometimes reapplies the launcher state
|
||||
|
||||
@@ -21,8 +21,10 @@ import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
|
||||
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.util.FloatProperty;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
@@ -57,6 +59,7 @@ public class AnimatorControllerWithResistance {
|
||||
private static final float RECENTS_SCALE_MAX_RESIST = 0.5f;
|
||||
|
||||
private static final TimeInterpolator RECENTS_SCALE_RESIST_INTERPOLATOR = DEACCEL;
|
||||
private static final TimeInterpolator RECENTS_TRANSLATE_RESIST_INTERPOLATOR = LINEAR;
|
||||
|
||||
private final AnimatorPlaybackController mNormalController;
|
||||
private final AnimatorPlaybackController mResistanceController;
|
||||
@@ -104,11 +107,14 @@ public class AnimatorControllerWithResistance {
|
||||
* @param dp Used to compute start and end values.
|
||||
* @param scaleTarget The target for the scaleProperty.
|
||||
* @param scaleProperty Animate the value to change the scale of the window/recents view.
|
||||
* @param translationTarget The target for the translationProperty.
|
||||
* @param translationProperty Animate the value to change the translation of the recents view.
|
||||
*/
|
||||
public static <SCALE> AnimatorControllerWithResistance createForRecents(
|
||||
public static <SCALE, TRANSLATION> AnimatorControllerWithResistance createForRecents(
|
||||
AnimatorPlaybackController normalController, Context context,
|
||||
RecentsOrientedState recentsOrientedState, DeviceProfile dp, SCALE scaleTarget,
|
||||
FloatProperty<SCALE> scaleProperty) {
|
||||
FloatProperty<SCALE> scaleProperty, TRANSLATION translationTarget,
|
||||
FloatProperty<TRANSLATION> translationProperty) {
|
||||
Rect startRect = new Rect();
|
||||
LauncherActivityInterface.INSTANCE.calculateTaskSize(context, dp, startRect,
|
||||
recentsOrientedState.getOrientationHandler());
|
||||
@@ -150,6 +156,19 @@ public class AnimatorControllerWithResistance {
|
||||
resistAnim.addFloat(scaleTarget, scaleProperty, startScale, endScale,
|
||||
scaleInterpolator);
|
||||
|
||||
if (!isTwoButtonMode) {
|
||||
// Compute where the task view would be based on the end scale, if we didn't translate.
|
||||
RectF endRectF = new RectF(startRect);
|
||||
Matrix temp = new Matrix();
|
||||
temp.setScale(RECENTS_SCALE_MAX_RESIST, RECENTS_SCALE_MAX_RESIST, pivot.x, pivot.y);
|
||||
temp.mapRect(endRectF);
|
||||
// Translate such that the task view touches the top of the screen when drag does.
|
||||
float endTranslation = endRectF.top * recentsOrientedState.getOrientationHandler()
|
||||
.getSecondaryTranslationDirectionFactor();
|
||||
resistAnim.addFloat(translationTarget, translationProperty, 0, endTranslation,
|
||||
RECENTS_TRANSLATE_RESIST_INTERPOLATOR);
|
||||
}
|
||||
|
||||
AnimatorPlaybackController resistanceController = resistAnim.createPlaybackController();
|
||||
return new AnimatorControllerWithResistance(normalController, resistanceController);
|
||||
}
|
||||
|
||||
@@ -107,6 +107,11 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
|
||||
action.call(target, 0, param);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void setSecondary(T target, Float2DAction<T> action, float param) {
|
||||
action.call(target, param, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPrimaryDirection(MotionEvent event, int pointerIndex) {
|
||||
return event.getY(pointerIndex);
|
||||
@@ -219,8 +224,7 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTaskDismissDirectionFactor() {
|
||||
public int getSecondaryTranslationDirectionFactor() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ public interface PagedOrientationHandler {
|
||||
|
||||
<T> void set(T target, Int2DAction<T> action, int param);
|
||||
<T> void set(T target, Float2DAction<T> action, float param);
|
||||
<T> void setSecondary(T target, Float2DAction<T> action, float param);
|
||||
float getPrimaryDirection(MotionEvent event, int pointerIndex);
|
||||
float getPrimaryVelocity(VelocityTracker velocityTracker, int pointerId);
|
||||
int getMeasuredSize(View view);
|
||||
@@ -75,7 +76,7 @@ public interface PagedOrientationHandler {
|
||||
int getScrollOffsetEnd(View view, Rect insets);
|
||||
SingleAxisSwipeDetector.Direction getOppositeSwipeDirection();
|
||||
int getPrimaryTranslationDirectionFactor();
|
||||
int getTaskDismissDirectionFactor();
|
||||
int getSecondaryTranslationDirectionFactor();
|
||||
int getTaskDragDisplacementFactor(boolean isRtl);
|
||||
ChildBounds getChildBounds(View child, int childStart, int pageCenter, boolean layoutChild);
|
||||
void setMaxScroll(AccessibilityEvent event, int maxScroll);
|
||||
|
||||
@@ -104,6 +104,11 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
|
||||
action.call(target, param, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void setSecondary(T target, Float2DAction<T> action, float param) {
|
||||
action.call(target, 0, param);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPrimaryDirection(MotionEvent event, int pointerIndex) {
|
||||
return event.getX(pointerIndex);
|
||||
@@ -216,8 +221,7 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTaskDismissDirectionFactor() {
|
||||
public int getSecondaryTranslationDirectionFactor() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import com.android.launcher3.Utilities;
|
||||
public class SeascapePagedViewHandler extends LandscapePagedViewHandler {
|
||||
|
||||
@Override
|
||||
public int getTaskDismissDirectionFactor() {
|
||||
public int getSecondaryTranslationDirectionFactor() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user