Loading quickstep/res/layout/overview_panel.xml +7 −6 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -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" /> Loading quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java +5 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)); Loading quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +10 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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; } /** Loading Loading @@ -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; } } quickstep/src/com/android/quickstep/views/LauncherRecentsView.java +2 −2 Original line number Diff line number Diff line Loading @@ -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); } } Loading quickstep/src/com/android/quickstep/views/RecentsView.java +135 −58 Original line number Diff line number Diff line Loading @@ -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; } }; Loading @@ -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 Loading Loading @@ -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(); Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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); Loading @@ -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; Loading Loading @@ -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(() -> { Loading Loading @@ -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 Loading Loading @@ -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; } /** Loading @@ -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(), Loading @@ -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) { Loading @@ -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); Loading @@ -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 Loading @@ -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(); } }); Loading @@ -2891,6 +2965,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T private void resetFromSplitSelectionState() { mSplitHiddenTaskView.setTranslationY(0); if (!showAsGrid()) { // TODO(b/186800707) int pageToSnapTo = mCurrentPage; if (mSplitHiddenTaskViewIndex <= pageToSnapTo) { pageToSnapTo += 1; Loading @@ -2898,6 +2974,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T pageToSnapTo = mSplitHiddenTaskViewIndex; } snapToPageImmediately(pageToSnapTo); } onLayout(false /* changed */, getLeft(), getTop(), getRight(), getBottom()); resetTaskVisuals(); mSplitHiddenTaskView = null; Loading Loading
quickstep/res/layout/overview_panel.xml +7 −6 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -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" /> Loading
quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java +5 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)); Loading
quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +10 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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; } /** Loading Loading @@ -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; } }
quickstep/src/com/android/quickstep/views/LauncherRecentsView.java +2 −2 Original line number Diff line number Diff line Loading @@ -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); } } Loading
quickstep/src/com/android/quickstep/views/RecentsView.java +135 −58 Original line number Diff line number Diff line Loading @@ -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; } }; Loading @@ -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 Loading Loading @@ -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(); Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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); Loading @@ -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; Loading Loading @@ -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(() -> { Loading Loading @@ -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 Loading Loading @@ -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; } /** Loading @@ -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(), Loading @@ -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) { Loading @@ -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); Loading @@ -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 Loading @@ -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(); } }); Loading @@ -2891,6 +2965,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T private void resetFromSplitSelectionState() { mSplitHiddenTaskView.setTranslationY(0); if (!showAsGrid()) { // TODO(b/186800707) int pageToSnapTo = mCurrentPage; if (mSplitHiddenTaskViewIndex <= pageToSnapTo) { pageToSnapTo += 1; Loading @@ -2898,6 +2974,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T pageToSnapTo = mSplitHiddenTaskViewIndex; } snapToPageImmediately(pageToSnapTo); } onLayout(false /* changed */, getLeft(), getTop(), getRight(), getBottom()); resetTaskVisuals(); mSplitHiddenTaskView = null; Loading