use of com.android.launcher3.util.PendingAnimation in project android_packages_apps_Launcher3 by crdroidandroid.
the class RecentsView method cancelSplitSelect.
public PendingAnimation cancelSplitSelect(boolean animate) {
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) {
resetFromSplitSelectionState();
return pendingAnim;
}
addViewInLayout(mSplitHiddenTaskView, mSplitHiddenTaskViewIndex, mSplitHiddenTaskView.getLayoutParams());
mSplitHiddenTaskView.setAlpha(0);
int[] oldScroll = new int[getChildCount()];
getPageScrolls(oldScroll, false, view -> view.getVisibility() != GONE && view != mSplitHiddenTaskView);
int[] newScroll = new int[getChildCount()];
getPageScrolls(newScroll, false, SIMPLE_SCROLL_LOGIC);
boolean needsCurveUpdates = false;
for (int i = mSplitHiddenTaskViewIndex; i >= 0; i--) {
View child = getChildAt(i);
if (child == mSplitHiddenTaskView) {
TaskView taskView = (TaskView) child;
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 {
// 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 ? ((TaskView) child).getPrimaryDismissTranslationProperty() : mOrientationHandler.getPrimaryViewTranslate();
ResourceProvider rp = DynamicResource.provider(mActivity);
SpringProperty sp = new SpringProperty(SpringProperty.FLAG_CAN_SPRING_ON_END).setDampingRatio(rp.getFloat(R.dimen.dismiss_task_trans_x_damping_ratio)).setStiffness(rp.getFloat(R.dimen.dismiss_task_trans_x_stiffness));
pendingAnim.add(ObjectAnimator.ofFloat(child, translationProperty, scrollDiff).setDuration(duration), ACCEL, sp);
needsCurveUpdates = true;
}
}
}
if (needsCurveUpdates) {
pendingAnim.addOnFrameCallback(this::updateCurveProperties);
}
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();
}
});
return pendingAnim;
}
use of com.android.launcher3.util.PendingAnimation in project android_packages_apps_Launcher3 by crdroidandroid.
the class RecentsView method createTaskDismissAnimation.
public PendingAnimation createTaskDismissAnimation(TaskView taskView, boolean animateTaskView, boolean shouldRemoveTask, long duration) {
if (mPendingAnimation != null) {
mPendingAnimation.createPlaybackController().dispatchOnCancel().dispatchOnEnd();
}
PendingAnimation anim = new PendingAnimation(duration);
int count = getPageCount();
if (count == 0) {
return anim;
}
int[] oldScroll = new int[count];
int[] newScroll = new int[count];
getPageScrolls(oldScroll, false, SIMPLE_SCROLL_LOGIC);
getPageScrolls(newScroll, false, (v) -> v.getVisibility() != GONE && v != taskView);
int taskCount = getTaskViewCount();
int scrollDiffPerPage = 0;
if (count > 1) {
scrollDiffPerPage = Math.abs(oldScroll[1] - oldScroll[0]);
}
int draggedIndex = indexOfChild(taskView);
boolean isFocusedTaskDismissed = taskView.getTask().key.id == mFocusedTaskId;
if (isFocusedTaskDismissed && showAsGrid()) {
anim.setFloat(mActionsView, VIEW_ALPHA, 0, clampToProgress(ACCEL_0_5, 0, 0.5f));
}
float dismissedTaskWidth = taskView.getLayoutParams().width + mPageSpacing;
boolean needsCurveUpdates = false;
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child == taskView) {
if (animateTaskView) {
addDismissedTaskAnimations(taskView, duration, anim);
}
} else if (!showAsGrid()) {
// Compute scroll offsets from task dismissal for animation.
// If we just take newScroll - oldScroll, everything to the right of dragged task
// translates to the left. We need to offset this in some cases:
// - In RTL, add page offset to all pages, since we want pages to move to the right
// Additionally, add a page offset if:
// - Current page is rightmost page (leftmost for RTL)
// - Dragging an adjacent page on the left side (right side for RTL)
int offset = mIsRtl ? scrollDiffPerPage : 0;
if (mCurrentPage == draggedIndex) {
int lastPage = taskCount - 1;
if (mCurrentPage == lastPage) {
offset += mIsRtl ? -scrollDiffPerPage : scrollDiffPerPage;
}
} else {
// Dragging an adjacent page.
// (Right in RTL, left in LTR)
int negativeAdjacent = mCurrentPage - 1;
if (draggedIndex == negativeAdjacent) {
offset += mIsRtl ? -scrollDiffPerPage : scrollDiffPerPage;
}
}
int scrollDiff = newScroll[i] - oldScroll[i] + offset;
if (scrollDiff != 0) {
FloatProperty translationProperty = child instanceof TaskView ? ((TaskView) child).getPrimaryDismissTranslationProperty() : mOrientationHandler.getPrimaryViewTranslate();
float additionalDismissDuration = ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET * Math.abs(i - draggedIndex);
anim.setFloat(child, translationProperty, scrollDiff, clampToProgress(LINEAR, Utilities.boundToRange(INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET + additionalDismissDuration, 0f, 1f), 1));
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile && child instanceof TaskView && ((TaskView) child).isRunningTask()) {
anim.addOnFrameCallback(() -> {
mLiveTileTaskViewSimulator.taskPrimaryTranslation.value = mOrientationHandler.getPrimaryValue(child.getTranslationX(), child.getTranslationY());
redrawLiveTile();
});
}
needsCurveUpdates = true;
}
} else if (child instanceof TaskView) {
// successive task dismissal durations for a staggered effect.
if (isFocusedTaskDismissed || (i >= draggedIndex && isSameGridRow((TaskView) child, taskView))) {
FloatProperty translationProperty = ((TaskView) child).getPrimaryDismissTranslationProperty();
float additionalDismissDuration = ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET * Math.abs(i - draggedIndex);
anim.setFloat(child, translationProperty, !mIsRtl ? -dismissedTaskWidth : dismissedTaskWidth, clampToProgress(LINEAR, Utilities.boundToRange(INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET + additionalDismissDuration, 0f, 1f), 1));
}
}
}
if (needsCurveUpdates) {
anim.addOnFrameCallback(this::updateCurveProperties);
}
// Add a tiny bit of translation Z, so that it draws on top of other views
if (animateTaskView) {
taskView.setTranslationZ(0.1f);
}
mPendingAnimation = anim;
mPendingAnimation.addEndListener(new Consumer<Boolean>() {
@Override
public void accept(Boolean success) {
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile && taskView.isRunningTask() && success) {
finishRecentsAnimation(true, /* toRecents */
false, /* shouldPip */
() -> onEnd(success));
} else {
onEnd(success);
}
}
@SuppressWarnings("WrongCall")
private void onEnd(boolean success) {
if (success) {
if (shouldRemoveTask) {
if (taskView.getTask() != null) {
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && taskView.isRunningTask()) {
finishRecentsAnimation(true, /* toRecents */
false, /* shouldPip */
() -> removeTaskInternal(taskView));
} else {
removeTaskInternal(taskView);
}
mActivity.getStatsLogManager().logger().withItemInfo(taskView.getItemInfo()).log(LAUNCHER_TASK_DISMISS_SWIPE_UP);
}
}
// Reset task translations as they may have updated via animations in
// createTaskDismissAnimation
resetTaskVisuals();
int pageToSnapTo = mCurrentPage;
// be at any page but the focused task always displays at the start.
if (taskView.getTask().key.id == mFocusedTaskId) {
pageToSnapTo = mTaskViewStartIndex;
} else if (draggedIndex < pageToSnapTo || pageToSnapTo == (getTaskViewCount() - 1)) {
pageToSnapTo -= 1;
}
removeViewInLayout(taskView);
if (getTaskViewCount() == 0) {
startHome();
} else {
snapToPageImmediately(pageToSnapTo);
dispatchScrollChanged();
// Grid got messed up, reapply.
updateGridProperties(true);
if (showAsGrid() && getFocusedTaskView() == null && mActionsView.getVisibilityAlpha().getValue() == 1) {
animateActionsViewOut();
}
}
// Update the layout synchronously so that the position of next view is
// immediately available.
onLayout(false, /* changed */
getLeft(), getTop(), getRight(), getBottom());
}
onDismissAnimationEnds();
mPendingAnimation = null;
}
});
return anim;
}
use of com.android.launcher3.util.PendingAnimation in project android_packages_apps_Launcher3 by crdroidandroid.
the class RecentsView method createTaskLaunchAnimation.
public PendingAnimation createTaskLaunchAnimation(TaskView tv, long duration, Interpolator interpolator) {
if (FeatureFlags.IS_STUDIO_BUILD && mPendingAnimation != null) {
throw new IllegalStateException("Another pending animation is still running");
}
int count = getTaskViewCount();
if (count == 0) {
return new PendingAnimation(duration);
}
// When swiping down from overview to tasks, ensures the snapped page's scroll maintain
// invariant between quick switch and overview, to ensure a smooth animation transition.
updateGridProperties();
updateScrollSynchronously();
int targetSysUiFlags = tv.getThumbnail().getSysUiStatusNavFlags();
final boolean[] passedOverviewThreshold = new boolean[] { false };
ValueAnimator progressAnim = ValueAnimator.ofFloat(0, 1);
progressAnim.addUpdateListener(animator -> {
// tasks' flags
if (animator.getAnimatedFraction() > UPDATE_SYSUI_FLAGS_THRESHOLD) {
mActivity.getSystemUiController().updateUiState(UI_STATE_FULLSCREEN_TASK, targetSysUiFlags);
} else {
mActivity.getSystemUiController().updateUiState(UI_STATE_FULLSCREEN_TASK, 0);
}
// Passing the threshold from taskview to fullscreen app will vibrate
final boolean passed = animator.getAnimatedFraction() >= SUCCESS_TRANSITION_PROGRESS;
if (passed != passedOverviewThreshold[0]) {
passedOverviewThreshold[0] = passed;
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
}
});
AnimatorSet anim = createAdjacentPageAnimForTaskLaunch(tv);
DepthController depthController = getDepthController();
if (depthController != null) {
ObjectAnimator depthAnimator = ObjectAnimator.ofFloat(depthController, DEPTH, BACKGROUND_APP.getDepth(mActivity));
anim.play(depthAnimator);
}
anim.play(progressAnim);
anim.setInterpolator(interpolator);
mPendingAnimation = new PendingAnimation(duration);
mPendingAnimation.add(anim);
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
mLiveTileTaskViewSimulator.addOverviewToAppAnim(mPendingAnimation, interpolator);
mPendingAnimation.addOnFrameCallback(this::redrawLiveTile);
}
mPendingAnimation.addEndListener(isSuccess -> {
if (isSuccess) {
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && tv.isRunningTask()) {
finishRecentsAnimation(false, /* toRecents */
null);
onTaskLaunchAnimationEnd(true);
} else {
tv.launchTask(this::onTaskLaunchAnimationEnd);
}
Task task = tv.getTask();
if (task != null) {
mActivity.getStatsLogManager().logger().withItemInfo(tv.getItemInfo()).log(LAUNCHER_TASK_LAUNCH_SWIPE_DOWN);
}
} else {
onTaskLaunchAnimationEnd(false);
}
mPendingAnimation = null;
});
return mPendingAnimation;
}
use of com.android.launcher3.util.PendingAnimation in project android_packages_apps_Launcher3 by crdroidandroid.
the class StaggeredWorkspaceAnim method addDepthAnimationForState.
private void addDepthAnimationForState(Launcher launcher, LauncherState state, long duration) {
if (!(launcher instanceof BaseQuickstepLauncher)) {
return;
}
PendingAnimation builder = new PendingAnimation(duration);
DepthController depthController = ((BaseQuickstepLauncher) launcher).getDepthController();
depthController.setStateWithAnimation(state, new StateAnimationConfig(), builder);
mAnimators.play(builder.buildAnim());
}
use of com.android.launcher3.util.PendingAnimation in project android_packages_apps_Launcher3 by crdroidandroid.
the class AnimatorControllerWithResistance method createForRecents.
/**
* Applies resistance to recents when swiping up past its target position.
* @param normalController The controller to run from 0 to 1 before this resistance applies.
* @param context Used to compute start and end values.
* @param recentsOrientedState Used to compute start and end values.
* @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, TRANSLATION> AnimatorControllerWithResistance createForRecents(AnimatorPlaybackController normalController, Context context, RecentsOrientedState recentsOrientedState, DeviceProfile dp, SCALE scaleTarget, FloatProperty<SCALE> scaleProperty, TRANSLATION translationTarget, FloatProperty<TRANSLATION> translationProperty) {
RecentsParams params = new RecentsParams(context, recentsOrientedState, dp, scaleTarget, scaleProperty, translationTarget, translationProperty);
PendingAnimation resistAnim = createRecentsResistanceAnim(params);
AnimatorPlaybackController resistanceController = resistAnim.createPlaybackController();
return new AnimatorControllerWithResistance(normalController, resistanceController);
}
Aggregations