Merge "Add funtional animation for SplitSelect from Grid." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
46d420bf14
@@ -15,12 +15,6 @@
|
||||
-->
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<com.android.quickstep.views.SplitPlaceholderView
|
||||
android:id="@+id/split_placeholder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/split_placeholder_size"
|
||||
android:background="@android:color/darker_gray"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.android.quickstep.views.LauncherRecentsView
|
||||
android:id="@+id/overview_panel"
|
||||
@@ -31,6 +25,13 @@
|
||||
android:clipToPadding="false"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<com.android.quickstep.views.SplitPlaceholderView
|
||||
android:id="@+id/split_placeholder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/split_placeholder_size"
|
||||
android:background="@android:color/darker_gray"
|
||||
android:visibility="gone" />
|
||||
|
||||
<include
|
||||
android:id="@+id/overview_actions_view"
|
||||
layout="@layout/overview_actions_container" />
|
||||
|
||||
@@ -22,12 +22,12 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FA
|
||||
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.SKIP_OVERVIEW;
|
||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||
import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
|
||||
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_PRIMARY_TRANSLATION;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_PRIMARY_SPLIT_TRANSLATION;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_SPLIT_TRANSLATION;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
|
||||
|
||||
import android.util.FloatProperty;
|
||||
@@ -97,10 +97,10 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
|
||||
PagedOrientationHandler orientationHandler =
|
||||
((RecentsView) mLauncher.getOverviewPanel()).getPagedOrientationHandler();
|
||||
FloatProperty taskViewsFloat = orientationHandler.getSplitSelectTaskOffset(
|
||||
TASK_PRIMARY_TRANSLATION, TASK_SECONDARY_TRANSLATION, mLauncher.getDeviceProfile());
|
||||
TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION,
|
||||
mLauncher.getDeviceProfile());
|
||||
setter.setFloat(mRecentsView, taskViewsFloat,
|
||||
toState.getOverviewSecondaryTranslation(mLauncher),
|
||||
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
|
||||
toState.getOverviewSecondaryTranslation(mLauncher), LINEAR);
|
||||
|
||||
setter.setFloat(mRecentsView, getContentAlphaProperty(), toState.overviewUi ? 1 : 0,
|
||||
config.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
|
||||
|
||||
@@ -25,6 +25,7 @@ import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITIO
|
||||
import android.animation.AnimatorSet;
|
||||
import android.app.ActivityOptions;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
@@ -64,6 +65,7 @@ public class SplitSelectStateController {
|
||||
private final SystemUiProxy mSystemUiProxy;
|
||||
private TaskView mInitialTaskView;
|
||||
private SplitPositionOption mInitialPosition;
|
||||
private Rect mInitialBounds;
|
||||
private final Handler mHandler;
|
||||
|
||||
public SplitSelectStateController(Handler handler, SystemUiProxy systemUiProxy) {
|
||||
@@ -74,9 +76,11 @@ public class SplitSelectStateController {
|
||||
/**
|
||||
* To be called after first task selected
|
||||
*/
|
||||
public void setInitialTaskSelect(TaskView taskView, SplitPositionOption positionOption) {
|
||||
public void setInitialTaskSelect(TaskView taskView, SplitPositionOption positionOption,
|
||||
Rect initialBounds) {
|
||||
mInitialTaskView = taskView;
|
||||
mInitialPosition = positionOption;
|
||||
mInitialBounds = initialBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,9 +224,14 @@ public class SplitSelectStateController {
|
||||
public void resetState() {
|
||||
mInitialTaskView = null;
|
||||
mInitialPosition = null;
|
||||
mInitialBounds = null;
|
||||
}
|
||||
|
||||
public boolean isSplitSelectActive() {
|
||||
return mInitialTaskView != null;
|
||||
}
|
||||
|
||||
public Rect getInitialBounds() {
|
||||
return mInitialBounds;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,8 +245,8 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher, Laun
|
||||
if (mActivity.isInState(OVERVIEW_SPLIT_SELECT)) {
|
||||
// We want to keep the tasks translations in this temporary state
|
||||
// after resetting the rest above
|
||||
setTaskViewsResistanceTranslation(mTaskViewsSecondaryTranslation);
|
||||
setTaskViewsPrimaryTranslation(mTaskViewsPrimaryTranslation);
|
||||
setTaskViewsPrimarySplitTranslation(mTaskViewsPrimarySplitTranslation);
|
||||
setTaskViewsSecondarySplitTranslation(mTaskViewsSecondarySplitTranslation);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -254,16 +254,29 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
* more specific, we'd want to create a similar FloatProperty just for a TaskView's
|
||||
* offsetX/Y property
|
||||
*/
|
||||
public static final FloatProperty<RecentsView> TASK_PRIMARY_TRANSLATION =
|
||||
new FloatProperty<RecentsView>("taskPrimaryTranslation") {
|
||||
public static final FloatProperty<RecentsView> TASK_PRIMARY_SPLIT_TRANSLATION =
|
||||
new FloatProperty<RecentsView>("taskPrimarySplitTranslation") {
|
||||
@Override
|
||||
public void setValue(RecentsView recentsView, float v) {
|
||||
recentsView.setTaskViewsPrimaryTranslation(v);
|
||||
recentsView.setTaskViewsPrimarySplitTranslation(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(RecentsView recentsView) {
|
||||
return recentsView.mTaskViewsPrimaryTranslation;
|
||||
return recentsView.mTaskViewsPrimarySplitTranslation;
|
||||
}
|
||||
};
|
||||
|
||||
public static final FloatProperty<RecentsView> TASK_SECONDARY_SPLIT_TRANSLATION =
|
||||
new FloatProperty<RecentsView>("taskSecondarySplitTranslation") {
|
||||
@Override
|
||||
public void setValue(RecentsView recentsView, float v) {
|
||||
recentsView.setTaskViewsSecondarySplitTranslation(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(RecentsView recentsView) {
|
||||
return recentsView.mTaskViewsSecondarySplitTranslation;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -279,7 +292,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
view.mLiveTileTaskViewSimulator.recentsViewScale.value = scale;
|
||||
view.updatePageOffsets();
|
||||
view.setTaskViewsResistanceTranslation(view.mTaskViewsSecondaryTranslation);
|
||||
view.setTaskViewsPrimaryTranslation(view.mTaskViewsPrimaryTranslation);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -363,7 +375,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
private float mAdjacentPageOffset = 0;
|
||||
protected float mTaskViewsSecondaryTranslation = 0;
|
||||
protected float mTaskViewsPrimaryTranslation = 0;
|
||||
protected float mTaskViewsPrimarySplitTranslation = 0;
|
||||
protected float mTaskViewsSecondarySplitTranslation = 0;
|
||||
// Progress from 0 to 1 where 0 is a carousel and 1 is a 2 row grid.
|
||||
private float mGridProgress = 0;
|
||||
private final IntSet mTopRowIdSet = new IntSet();
|
||||
@@ -1848,15 +1861,28 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
final int boxLength = Math.max(mLastComputedGridTaskSize.width(),
|
||||
mLastComputedGridTaskSize.height());
|
||||
int taskTopMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
|
||||
float heightOffset = (boxLength + taskTopMargin) + mRowSpacing;
|
||||
float taskGridVerticalDiff = mLastComputedGridTaskSize.top - mLastComputedTaskSize.top;
|
||||
|
||||
/*
|
||||
* taskGridVerticalDiff is used to position the top of a task in the top row of the grid
|
||||
* heightOffset is the vertical space one grid task takes + space between top and
|
||||
* bottom row
|
||||
* Summed together they provide the top position for bottom row of grid tasks
|
||||
*/
|
||||
final float taskGridVerticalDiff =
|
||||
mLastComputedGridTaskSize.top - mLastComputedTaskSize.top;
|
||||
final float heightOffset = (boxLength + taskTopMargin) + mRowSpacing;
|
||||
|
||||
int topRowWidth = 0;
|
||||
int bottomRowWidth = 0;
|
||||
float topAccumulatedTranslationX = 0;
|
||||
float bottomAccumulatedTranslationX = 0;
|
||||
|
||||
// Contains whether the child index is in top or bottom of grid (for non-focused task)
|
||||
// Different from mTopRowIdSet, which contains the taskId of what task is in top row
|
||||
IntSet topSet = new IntSet();
|
||||
IntSet bottomSet = new IntSet();
|
||||
|
||||
// Horizontal grid translation for each task
|
||||
float[] gridTranslations = new float[taskCount];
|
||||
|
||||
int focusedTaskIndex = Integer.MAX_VALUE;
|
||||
@@ -1910,7 +1936,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
boolean isTopRow = isTaskDismissal ? mTopRowIdSet.contains(taskId)
|
||||
: topRowWidth <= bottomRowWidth;
|
||||
if (isTopRow) {
|
||||
gridTranslations[i] += topAccumulatedTranslationX;
|
||||
topRowWidth += taskWidthAndSpacing;
|
||||
topSet.add(i);
|
||||
mTopRowIdSet.add(taskId);
|
||||
@@ -1926,11 +1951,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
widthOffset += getTaskViewAt(j).getLayoutParams().width + mPageSpacing;
|
||||
}
|
||||
|
||||
float gridTranslationX = mIsRtl ? widthOffset : -widthOffset;
|
||||
gridTranslations[i] += gridTranslationX;
|
||||
topAccumulatedTranslationX += gridTranslationX;
|
||||
float currentTaskTranslationX = mIsRtl ? widthOffset : -widthOffset;
|
||||
gridTranslations[i] += topAccumulatedTranslationX + currentTaskTranslationX;
|
||||
topAccumulatedTranslationX += currentTaskTranslationX;
|
||||
} else {
|
||||
gridTranslations[i] += bottomAccumulatedTranslationX;
|
||||
bottomRowWidth += taskWidthAndSpacing;
|
||||
bottomSet.add(i);
|
||||
|
||||
@@ -1946,9 +1970,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
widthOffset += getTaskViewAt(j).getLayoutParams().width + mPageSpacing;
|
||||
}
|
||||
|
||||
float gridTranslationX = mIsRtl ? widthOffset : -widthOffset;
|
||||
gridTranslations[i] += gridTranslationX;
|
||||
bottomAccumulatedTranslationX += gridTranslationX;
|
||||
float currentTaskTranslationX = mIsRtl ? widthOffset : -widthOffset;
|
||||
gridTranslations[i] += bottomAccumulatedTranslationX + currentTaskTranslationX;
|
||||
bottomAccumulatedTranslationX += currentTaskTranslationX;
|
||||
}
|
||||
if (taskView == snappedTaskView) {
|
||||
snappedTaskRowWidth = isTopRow ? topRowWidth : bottomRowWidth;
|
||||
@@ -2139,18 +2163,43 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// Use setFloat instead of setViewAlpha as we want to keep the view visible even when it's
|
||||
// alpha is set to 0 so that it can be recycled in the view pool properly
|
||||
anim.setFloat(taskView, VIEW_ALPHA, 0, ACCEL_2);
|
||||
FloatProperty<TaskView> secondaryViewTranslate =
|
||||
taskView.getSecondaryDissmissTranslationProperty();
|
||||
int secondaryTaskDimension = mOrientationHandler.getSecondaryDimension(taskView);
|
||||
int verticalFactor = mOrientationHandler.getSecondaryTranslationDirectionFactor();
|
||||
SplitSelectStateController splitController = mSplitPlaceholderView.getSplitController();
|
||||
|
||||
ResourceProvider rp = DynamicResource.provider(mActivity);
|
||||
SpringProperty sp = new SpringProperty(SpringProperty.FLAG_CAN_SPRING_ON_START)
|
||||
.setDampingRatio(rp.getFloat(R.dimen.dismiss_task_trans_y_damping_ratio))
|
||||
.setStiffness(rp.getFloat(R.dimen.dismiss_task_trans_y_stiffness));
|
||||
FloatProperty<TaskView> dismissingTaskViewTranslate =
|
||||
taskView.getSecondaryDissmissTranslationProperty();;
|
||||
// TODO(b/186800707) translate entire grid size distance
|
||||
int translateDistance = mOrientationHandler.getSecondaryDimension(taskView);
|
||||
int positiveNegativeFactor = mOrientationHandler.getSecondaryTranslationDirectionFactor();
|
||||
if (splitController.isSplitSelectActive()) {
|
||||
// Have the task translate towards whatever side was just pinned
|
||||
int dir = mOrientationHandler.getSplitTaskViewDismissDirection(splitController
|
||||
.getActiveSplitPositionOption(), mActivity.getDeviceProfile());
|
||||
switch (dir) {
|
||||
case PagedOrientationHandler.SPLIT_TRANSLATE_SECONDARY_NEGATIVE:
|
||||
dismissingTaskViewTranslate = taskView
|
||||
.getSecondaryDissmissTranslationProperty();
|
||||
positiveNegativeFactor = -1;
|
||||
break;
|
||||
|
||||
anim.add(ObjectAnimator.ofFloat(taskView, secondaryViewTranslate,
|
||||
verticalFactor * secondaryTaskDimension).setDuration(duration), LINEAR, sp);
|
||||
case PagedOrientationHandler.SPLIT_TRANSLATE_PRIMARY_POSITIVE:
|
||||
dismissingTaskViewTranslate = taskView.getPrimaryDismissTranslationProperty();
|
||||
positiveNegativeFactor = 1;
|
||||
break;
|
||||
|
||||
case PagedOrientationHandler.SPLIT_TRANSLATE_PRIMARY_NEGATIVE:
|
||||
dismissingTaskViewTranslate = taskView.getPrimaryDismissTranslationProperty();
|
||||
positiveNegativeFactor = -1;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Invalid split task translation: " + dir);
|
||||
}
|
||||
}
|
||||
anim.add(ObjectAnimator.ofFloat(taskView, dismissingTaskViewTranslate,
|
||||
positiveNegativeFactor * translateDistance).setDuration(duration), LINEAR, sp);
|
||||
|
||||
if (LIVE_TILE.get() && taskView.isRunningTask()) {
|
||||
anim.addOnFrameCallback(() -> {
|
||||
@@ -2215,18 +2264,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
}
|
||||
|
||||
// Additional offset for fake landscape, if the pinning happens to the right or
|
||||
// left, we need to scroll all the tasks away from the direction of the splaceholder
|
||||
// view
|
||||
if (isSplitSelectionActive()) {
|
||||
int splitPosition = getSplitPlaceholder().getSplitController()
|
||||
.getActiveSplitPositionOption().mStagePosition;
|
||||
int direction = mOrientationHandler
|
||||
.getSplitTranslationDirectionFactor(splitPosition);
|
||||
int splitOffset = mOrientationHandler.getSplitAnimationTranslation(
|
||||
mSplitPlaceholderView.getHeight(), mActivity.getDeviceProfile());
|
||||
offset += direction * splitOffset;
|
||||
}
|
||||
int scrollDiff = newScroll[i] - oldScroll[i] + offset;
|
||||
if (scrollDiff != 0) {
|
||||
FloatProperty translationProperty = child instanceof TaskView
|
||||
@@ -2769,13 +2806,20 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mLiveTileTaskViewSimulator.recentsViewSecondaryTranslation.value = translation;
|
||||
}
|
||||
|
||||
protected void setTaskViewsPrimaryTranslation(float translation) {
|
||||
mTaskViewsPrimaryTranslation = translation;
|
||||
protected void setTaskViewsPrimarySplitTranslation(float translation) {
|
||||
mTaskViewsPrimarySplitTranslation = translation;
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
TaskView task = getTaskViewAt(i);
|
||||
task.getPrimaryDismissTranslationProperty().set(task, translation / getScaleY());
|
||||
task.getPrimarySplitTranslationProperty().set(task, translation);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setTaskViewsSecondarySplitTranslation(float translation) {
|
||||
mTaskViewsSecondarySplitTranslation = translation;
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
TaskView task = getTaskViewAt(i);
|
||||
task.getSecondarySplitTranslationProperty().set(task, translation);
|
||||
}
|
||||
mLiveTileTaskViewSimulator.recentsViewPrimaryTranslation.value = translation;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2798,8 +2842,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
public void initiateSplitSelect(TaskView taskView, SplitPositionOption splitPositionOption) {
|
||||
mSplitHiddenTaskView = taskView;
|
||||
SplitSelectStateController splitController = mSplitPlaceholderView.getSplitController();
|
||||
splitController.setInitialTaskSelect(taskView,
|
||||
splitPositionOption);
|
||||
Rect initialBounds = new Rect(taskView.getLeft(), taskView.getTop(), taskView.getRight(),
|
||||
taskView.getBottom());
|
||||
splitController.setInitialTaskSelect(taskView, splitPositionOption, initialBounds);
|
||||
mSplitHiddenTaskViewIndex = indexOfChild(taskView);
|
||||
mSplitPlaceholderView.setLayoutParams(
|
||||
splitController.getLayoutParamsForActivePosition(getResources(),
|
||||
@@ -2819,7 +2864,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
|
||||
public PendingAnimation cancelSplitSelect(boolean animate) {
|
||||
mSplitPlaceholderView.getSplitController().resetState();
|
||||
SplitSelectStateController splitController = mSplitPlaceholderView.getSplitController();
|
||||
SplitPositionOption splitOption = splitController.getActiveSplitPositionOption();
|
||||
Rect initialBounds = splitController.getInitialBounds();
|
||||
splitController.resetState();
|
||||
int duration = mActivity.getStateManager().getState().getTransitionDuration(getContext());
|
||||
PendingAnimation pendingAnim = new PendingAnimation(duration);
|
||||
if (!animate) {
|
||||
@@ -2834,8 +2882,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
getPageScrolls(oldScroll, false,
|
||||
view -> view.getVisibility() != GONE && view != mSplitHiddenTaskView);
|
||||
|
||||
// x is correct, y is before tasks move up
|
||||
int[] locationOnScreen = mSplitHiddenTaskView.getLocationOnScreen();
|
||||
int[] newScroll = new int[getChildCount()];
|
||||
getPageScrolls(newScroll, false, SIMPLE_SCROLL_LOGIC);
|
||||
|
||||
@@ -2843,20 +2889,42 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
for (int i = mSplitHiddenTaskViewIndex; i >= 0; i--) {
|
||||
View child = getChildAt(i);
|
||||
if (child == mSplitHiddenTaskView) {
|
||||
TaskView taskView = (TaskView) child;
|
||||
|
||||
int left = newScroll[i] + getPaddingStart();
|
||||
int topMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
|
||||
int top = -mSplitHiddenTaskView.getHeight() - locationOnScreen[1];
|
||||
mSplitHiddenTaskView.layout(left, top,
|
||||
left + mSplitHiddenTaskView.getWidth(),
|
||||
top + mSplitHiddenTaskView.getHeight());
|
||||
pendingAnim.add(ObjectAnimator.ofFloat(mSplitHiddenTaskView, TRANSLATION_Y,
|
||||
-top + mSplitPlaceholderView.getHeight() - topMargin));
|
||||
int dir = mOrientationHandler.getSplitTaskViewDismissDirection(splitOption,
|
||||
mActivity.getDeviceProfile());
|
||||
FloatProperty<TaskView> dismissingTaskViewTranslate;
|
||||
Rect hiddenBounds = new Rect(taskView.getLeft(), taskView.getTop(),
|
||||
taskView.getRight(), taskView.getBottom());
|
||||
int distanceDelta = 0;
|
||||
if (dir == PagedOrientationHandler.SPLIT_TRANSLATE_SECONDARY_NEGATIVE) {
|
||||
dismissingTaskViewTranslate = taskView
|
||||
.getSecondaryDissmissTranslationProperty();
|
||||
distanceDelta = initialBounds.top - hiddenBounds.top;
|
||||
taskView.layout(initialBounds.left, hiddenBounds.top, initialBounds.right,
|
||||
hiddenBounds.bottom);
|
||||
} else {
|
||||
dismissingTaskViewTranslate = taskView
|
||||
.getPrimaryDismissTranslationProperty();
|
||||
distanceDelta = initialBounds.left - hiddenBounds.left;
|
||||
taskView.layout(hiddenBounds.left, initialBounds.top, hiddenBounds.right,
|
||||
initialBounds.bottom);
|
||||
if (dir == PagedOrientationHandler.SPLIT_TRANSLATE_PRIMARY_POSITIVE) {
|
||||
distanceDelta *= -1;
|
||||
}
|
||||
}
|
||||
pendingAnim.add(ObjectAnimator.ofFloat(mSplitHiddenTaskView,
|
||||
dismissingTaskViewTranslate,
|
||||
distanceDelta));
|
||||
pendingAnim.add(ObjectAnimator.ofFloat(mSplitHiddenTaskView, ALPHA, 1));
|
||||
} else {
|
||||
// If insertion is on last index (furthest from clear all), we directly add the view
|
||||
// else we translate all views to the right of insertion index further right,
|
||||
// ignore views to left
|
||||
if (showAsGrid()) {
|
||||
// TODO(b/186800707) handle more elegantly for grid
|
||||
continue;
|
||||
}
|
||||
int scrollDiff = newScroll[i] - oldScroll[i];
|
||||
if (scrollDiff != 0) {
|
||||
FloatProperty translationProperty = child instanceof TaskView
|
||||
@@ -2882,6 +2950,12 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
pendingAnim.addListener(new AnimationSuccessListener() {
|
||||
@Override
|
||||
public void onAnimationSuccess(Animator animator) {
|
||||
// TODO(b/186800707) Figure out how to undo for grid view
|
||||
// Need to handle cases where dismissed task is
|
||||
// * Top Row
|
||||
// * Bottom Row
|
||||
// * Focused Task
|
||||
updateGridProperties();
|
||||
resetFromSplitSelectionState();
|
||||
}
|
||||
});
|
||||
@@ -2891,13 +2965,16 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
private void resetFromSplitSelectionState() {
|
||||
mSplitHiddenTaskView.setTranslationY(0);
|
||||
int pageToSnapTo = mCurrentPage;
|
||||
if (mSplitHiddenTaskViewIndex <= pageToSnapTo) {
|
||||
pageToSnapTo += 1;
|
||||
} else {
|
||||
pageToSnapTo = mSplitHiddenTaskViewIndex;
|
||||
if (!showAsGrid()) {
|
||||
// TODO(b/186800707)
|
||||
int pageToSnapTo = mCurrentPage;
|
||||
if (mSplitHiddenTaskViewIndex <= pageToSnapTo) {
|
||||
pageToSnapTo += 1;
|
||||
} else {
|
||||
pageToSnapTo = mSplitHiddenTaskViewIndex;
|
||||
}
|
||||
snapToPageImmediately(pageToSnapTo);
|
||||
}
|
||||
snapToPageImmediately(pageToSnapTo);
|
||||
onLayout(false /* changed */, getLeft(), getTop(), getRight(), getBottom());
|
||||
resetTaskVisuals();
|
||||
mSplitHiddenTaskView = null;
|
||||
|
||||
@@ -172,6 +172,32 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
}
|
||||
};
|
||||
|
||||
private static final FloatProperty<TaskView> SPLIT_SELECT_TRANSLATION_X =
|
||||
new FloatProperty<TaskView>("splitSelectTranslationX") {
|
||||
@Override
|
||||
public void setValue(TaskView taskView, float v) {
|
||||
taskView.setSplitSelectTranslationX(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(TaskView taskView) {
|
||||
return taskView.mSplitSelectTranslationX;
|
||||
}
|
||||
};
|
||||
|
||||
private static final FloatProperty<TaskView> SPLIT_SELECT_TRANSLATION_Y =
|
||||
new FloatProperty<TaskView>("splitSelectTranslationY") {
|
||||
@Override
|
||||
public void setValue(TaskView taskView, float v) {
|
||||
taskView.setSplitSelectTranslationY(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(TaskView taskView) {
|
||||
return taskView.mSplitSelectTranslationY;
|
||||
}
|
||||
};
|
||||
|
||||
private static final FloatProperty<TaskView> DISMISS_TRANSLATION_X =
|
||||
new FloatProperty<TaskView>("dismissTranslationX") {
|
||||
@Override
|
||||
@@ -345,6 +371,9 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
// The following grid translations scales with mGridProgress.
|
||||
private float mGridTranslationX;
|
||||
private float mGridTranslationY;
|
||||
// Used when in SplitScreenSelectState
|
||||
private float mSplitSelectTranslationY;
|
||||
private float mSplitSelectTranslationX;
|
||||
|
||||
private ObjectAnimator mIconAndDimAnimator;
|
||||
private float mIconScaleAnimStartProgress = 0;
|
||||
@@ -826,8 +855,10 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
protected void resetViewTransforms() {
|
||||
// fullscreenTranslation and accumulatedTranslation should not be reset, as
|
||||
// resetViewTransforms is called during Quickswitch scrolling.
|
||||
mDismissTranslationX = mTaskOffsetTranslationX = mTaskResistanceTranslationX = 0f;
|
||||
mDismissTranslationY = mTaskOffsetTranslationY = mTaskResistanceTranslationY = 0f;
|
||||
mDismissTranslationX = mTaskOffsetTranslationX = mTaskResistanceTranslationX =
|
||||
mSplitSelectTranslationX = 0f;
|
||||
mDismissTranslationY = mTaskOffsetTranslationY = mTaskResistanceTranslationY =
|
||||
mSplitSelectTranslationY = 0f;
|
||||
applyTranslationX();
|
||||
applyTranslationY();
|
||||
setTranslationZ(0);
|
||||
@@ -957,6 +988,15 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
setScaleY(scale);
|
||||
}
|
||||
|
||||
private void setSplitSelectTranslationX(float x) {
|
||||
mSplitSelectTranslationX = x;
|
||||
applyTranslationX();
|
||||
}
|
||||
|
||||
private void setSplitSelectTranslationY(float y) {
|
||||
mSplitSelectTranslationY = y;
|
||||
applyTranslationY();
|
||||
}
|
||||
private void setDismissTranslationX(float x) {
|
||||
mDismissTranslationX = x;
|
||||
applyTranslationX();
|
||||
@@ -1057,12 +1097,12 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
|
||||
private void applyTranslationX() {
|
||||
setTranslationX(mDismissTranslationX + mTaskOffsetTranslationX + mTaskResistanceTranslationX
|
||||
+ getPersistentTranslationX());
|
||||
+ mSplitSelectTranslationX + getPersistentTranslationX());
|
||||
}
|
||||
|
||||
private void applyTranslationY() {
|
||||
setTranslationY(mDismissTranslationY + mTaskOffsetTranslationY + mTaskResistanceTranslationY
|
||||
+ getPersistentTranslationY());
|
||||
+ mSplitSelectTranslationY + getPersistentTranslationY());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1086,6 +1126,16 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
+ getGridTrans(mGridTranslationY);
|
||||
}
|
||||
|
||||
public FloatProperty<TaskView> getPrimarySplitTranslationProperty() {
|
||||
return getPagedOrientationHandler().getPrimaryValue(
|
||||
SPLIT_SELECT_TRANSLATION_X, SPLIT_SELECT_TRANSLATION_Y);
|
||||
}
|
||||
|
||||
public FloatProperty<TaskView> getSecondarySplitTranslationProperty() {
|
||||
return getPagedOrientationHandler().getSecondaryValue(
|
||||
SPLIT_SELECT_TRANSLATION_X, SPLIT_SELECT_TRANSLATION_Y);
|
||||
}
|
||||
|
||||
public FloatProperty<TaskView> getPrimaryDismissTranslationProperty() {
|
||||
return getPagedOrientationHandler().getPrimaryValue(
|
||||
DISMISS_TRANSLATION_X, DISMISS_TRANSLATION_Y);
|
||||
|
||||
@@ -159,6 +159,19 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
|
||||
return VIEW_TRANSLATE_X;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition,
|
||||
DeviceProfile dp) {
|
||||
// Don't use device profile here because we know we're in fake landscape, only split option
|
||||
// available is top/left
|
||||
if (splitPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT) {
|
||||
// Top (visually left) side
|
||||
return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
|
||||
}
|
||||
throw new IllegalStateException("Invalid split stage position: " +
|
||||
splitPosition.mStagePosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrimaryScroll(View view) {
|
||||
return view.getScrollY();
|
||||
|
||||
@@ -42,6 +42,10 @@ import java.util.List;
|
||||
*/
|
||||
public interface PagedOrientationHandler {
|
||||
|
||||
int SPLIT_TRANSLATE_PRIMARY_POSITIVE = 0;
|
||||
int SPLIT_TRANSLATE_PRIMARY_NEGATIVE = 1;
|
||||
int SPLIT_TRANSLATE_SECONDARY_NEGATIVE = 2;
|
||||
|
||||
PagedOrientationHandler PORTRAIT = new PortraitPagedViewHandler();
|
||||
PagedOrientationHandler LANDSCAPE = new LandscapePagedViewHandler();
|
||||
PagedOrientationHandler SEASCAPE = new SeascapePagedViewHandler();
|
||||
@@ -71,6 +75,13 @@ public interface PagedOrientationHandler {
|
||||
int getSecondaryDimension(View view);
|
||||
FloatProperty<View> getPrimaryViewTranslate();
|
||||
FloatProperty<View> getSecondaryViewTranslate();
|
||||
|
||||
/**
|
||||
* @param splitPosition The position where the view to be split will go
|
||||
* @return {@link #SPLIT_TRANSLATE_*} constants to indicate which direction the
|
||||
* dismissal should happen
|
||||
*/
|
||||
int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition, DeviceProfile dp);
|
||||
int getPrimaryScroll(View view);
|
||||
float getPrimaryScale(View view);
|
||||
int getChildStart(View view);
|
||||
|
||||
@@ -155,6 +155,25 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
|
||||
return VIEW_TRANSLATE_Y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition,
|
||||
DeviceProfile dp) {
|
||||
if (splitPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT) {
|
||||
if (dp.isLandscape) {
|
||||
// Left side
|
||||
return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
|
||||
} else {
|
||||
// Top side
|
||||
return SPLIT_TRANSLATE_SECONDARY_NEGATIVE;
|
||||
}
|
||||
} else if (splitPosition.mStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
|
||||
// We don't have a bottom option, so should be right
|
||||
return SPLIT_TRANSLATE_PRIMARY_POSITIVE;
|
||||
}
|
||||
throw new IllegalStateException("Invalid split stage position: " +
|
||||
splitPosition.mStagePosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrimaryScroll(View view) {
|
||||
return view.getScrollX();
|
||||
|
||||
Reference in New Issue
Block a user