use of com.android.launcher3.util.PendingAnimation in project android_packages_apps_Trebuchet by LineageOS.
the class RecentsView method createTaskDismissAnimation.
public PendingAnimation createTaskDismissAnimation(TaskView taskView, boolean animateTaskView, boolean shouldRemoveTask, long duration) {
if (mPendingAnimation != null) {
mPendingAnimation.finish(false, Touch.SWIPE);
}
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 needsCurveUpdates = false;
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child == taskView) {
if (animateTaskView) {
addDismissedTaskAnimations(taskView, duration, anim);
}
} else {
// 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).getPrimaryFillDismissGapTranslationProperty() : 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));
anim.add(ObjectAnimator.ofFloat(child, translationProperty, scrollDiff).setDuration(duration), ACCEL, sp);
needsCurveUpdates = true;
}
}
}
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<EndState>() {
@Override
public void accept(EndState endState) {
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && taskView.isRunningTask() && endState.isSuccess) {
finishRecentsAnimation(true, /* toHome */
() -> onEnd(endState));
} else {
onEnd(endState);
}
}
@SuppressWarnings("WrongCall")
private void onEnd(EndState endState) {
if (endState.isSuccess) {
if (shouldRemoveTask) {
removeTask(taskView, draggedIndex, endState);
}
int pageToSnapTo = mCurrentPage;
if (draggedIndex < pageToSnapTo || pageToSnapTo == (getTaskViewCount() - 1)) {
pageToSnapTo -= 1;
}
removeViewInLayout(taskView);
if (getTaskViewCount() == 0) {
removeViewInLayout(mClearAllButton);
startHome();
} else {
snapToPageImmediately(pageToSnapTo);
}
// Update the layout synchronously so that the position of next view is
// immediately available.
onLayout(false, /* changed */
getLeft(), getTop(), getRight(), getBottom());
}
resetTaskVisuals();
mPendingAnimation = null;
}
});
return anim;
}
use of com.android.launcher3.util.PendingAnimation in project android_packages_apps_Trebuchet by LineageOS.
the class RecentsView method runDismissAnimation.
protected void runDismissAnimation(PendingAnimation pendingAnim) {
AnimatorPlaybackController controller = pendingAnim.createPlaybackController();
controller.dispatchOnStart();
controller.setEndAction(() -> pendingAnim.finish(true, Touch.SWIPE));
controller.getAnimationPlayer().setInterpolator(FAST_OUT_SLOW_IN);
controller.start();
}
use of com.android.launcher3.util.PendingAnimation in project android_packages_apps_Trebuchet by LineageOS.
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);
}
int targetSysUiFlags = tv.getThumbnail().getSysUiStatusNavFlags();
final boolean[] passedOverviewThreshold = new boolean[] { false };
ValueAnimator progressAnim = ValueAnimator.ofFloat(0, 1);
progressAnim.addUpdateListener(animator -> {
// Once we pass a certain threshold, update the sysui flags to match the target
// tasks' flags
mActivity.getSystemUiController().updateUiState(UI_STATE_OVERVIEW, animator.getAnimatedFraction() > UPDATE_SYSUI_FLAGS_THRESHOLD ? targetSysUiFlags : 0);
onTaskLaunchAnimationUpdate(animator.getAnimatedFraction(), tv);
// 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);
mPendingAnimation.addEndListener((endState) -> {
if (endState.isSuccess) {
Consumer<Boolean> onLaunchResult = (result) -> {
onTaskLaunchAnimationEnd(result);
if (!result) {
tv.notifyTaskLaunchFailed(TAG);
}
};
tv.launchTask(false, onLaunchResult, getHandler());
Task task = tv.getTask();
if (task != null) {
mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(endState.logAction, Direction.DOWN, indexOfChild(tv), TaskUtils.getLaunchComponentKeyForTask(task.key));
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_Trebuchet by LineageOS.
the class RecentsView method addDismissedTaskAnimations.
private void addDismissedTaskAnimations(View taskView, long duration, PendingAnimation anim) {
// 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<View> secondaryViewTranslate = mOrientationHandler.getSecondaryViewTranslate();
int secondaryTaskDimension = mOrientationHandler.getSecondaryDimension(taskView);
int verticalFactor = mOrientationHandler.getSecondaryTranslationDirectionFactor();
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));
anim.add(ObjectAnimator.ofFloat(taskView, secondaryViewTranslate, verticalFactor * secondaryTaskDimension).setDuration(duration), LINEAR, sp);
}
use of com.android.launcher3.util.PendingAnimation in project android_packages_apps_Trebuchet by LineageOS.
the class AllAppsEduView method playAnimation.
private void playAnimation() {
if (mAnimation != null) {
return;
}
mAnimation = new AnimatorSet();
final Rect circleBoundsOg = new Rect(mCircle.getBounds());
final Rect gradientBoundsOg = new Rect(mGradient.getBounds());
final Rect temp = new Rect();
final float transY = mMaxHeightPx - mCircleSizePx - mPaddingPx;
// 1st: Circle alpha/scale
int firstPart = 600;
// 2nd: Circle animates upwards, Gradient alpha fades in, Gradient grows, All Apps hint
int secondPart = 1200;
int introDuration = firstPart + secondPart;
StateAnimationConfig config = new StateAnimationConfig();
config.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(ACCEL, 0, 0.08f));
config.duration = secondPart;
config.userControlled = false;
AnimatorPlaybackController stateAnimationController = mLauncher.getStateManager().createAnimationToNewWorkspace(ALL_APPS, config);
float maxAllAppsProgress = mLauncher.getDeviceProfile().isLandscape ? 0.35f : 0.15f;
AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
PendingAnimation allAppsAlpha = new PendingAnimation(config.duration);
allAppsController.setAlphas(ALL_APPS, config, allAppsAlpha);
mAnimation.play(allAppsAlpha.buildAnim());
ValueAnimator intro = ValueAnimator.ofFloat(0, 1f);
intro.setInterpolator(LINEAR);
intro.setDuration(introDuration);
intro.addUpdateListener((new MultiValueUpdateListener() {
FloatProp mCircleAlpha = new FloatProp(0, 255, 0, firstPart, LINEAR);
FloatProp mCircleScale = new FloatProp(2f, 1f, 0, firstPart, OVERSHOOT_1_7);
FloatProp mDeltaY = new FloatProp(0, transY, firstPart, secondPart, FAST_OUT_SLOW_IN);
FloatProp mGradientAlpha = new FloatProp(0, 255, firstPart, secondPart * 0.3f, LINEAR);
@Override
public void onUpdate(float progress) {
temp.set(circleBoundsOg);
temp.offset(0, (int) -mDeltaY.value);
Utilities.scaleRectAboutCenter(temp, mCircleScale.value);
mCircle.setBounds(temp);
mCircle.setAlpha((int) mCircleAlpha.value);
mGradient.setAlpha((int) mGradientAlpha.value);
temp.set(gradientBoundsOg);
temp.top -= mDeltaY.value;
mGradient.setBounds(temp);
invalidate();
float stateProgress = Utilities.mapToRange(mDeltaY.value, 0, transY, 0, maxAllAppsProgress, LINEAR);
stateAnimationController.setPlayFraction(stateProgress);
}
}));
intro.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mCircle.setAlpha(0);
mGradient.setAlpha(0);
}
});
mAnimation.play(intro);
ValueAnimator closeAllApps = ValueAnimator.ofFloat(maxAllAppsProgress, 0f);
closeAllApps.addUpdateListener(valueAnimator -> {
stateAnimationController.setPlayFraction((float) valueAnimator.getAnimatedValue());
});
closeAllApps.setInterpolator(FAST_OUT_SLOW_IN);
closeAllApps.setStartDelay(introDuration);
closeAllApps.setDuration(250);
mAnimation.play(closeAllApps);
mAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mAnimation = null;
// Handles cancelling the animation used to hint towards All Apps.
mLauncher.getStateManager().goToState(NORMAL, false);
handleClose(false);
}
});
mAnimation.start();
}
Aggregations