Search in sources :

Example 11 with PendingAnimation

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;
}
Also used : PendingAnimation(com.android.launcher3.anim.PendingAnimation) SpringProperty(com.android.launcher3.anim.SpringProperty) Rect(android.graphics.Rect) ImageView(android.widget.ImageView) View(android.view.View) ListView(android.widget.ListView) PagedView(com.android.launcher3.PagedView) TextPaint(android.text.TextPaint) Point(android.graphics.Point) ValueAnimator(android.animation.ValueAnimator) Animator(android.animation.Animator) ObjectAnimator(android.animation.ObjectAnimator) SplitPositionOption(com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption) ResourceProvider(com.android.systemui.plugins.ResourceProvider) SplitSelectStateController(com.android.quickstep.util.SplitSelectStateController) FloatProperty(android.util.FloatProperty) AnimationSuccessListener(com.android.launcher3.anim.AnimationSuccessListener)

Example 12 with PendingAnimation

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;
}
Also used : PendingAnimation(com.android.launcher3.anim.PendingAnimation) FloatProperty(android.util.FloatProperty) ImageView(android.widget.ImageView) View(android.view.View) ListView(android.widget.ListView) PagedView(com.android.launcher3.PagedView) TextPaint(android.text.TextPaint) Point(android.graphics.Point)

Example 13 with PendingAnimation

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;
}
Also used : PendingAnimation(com.android.launcher3.anim.PendingAnimation) Task(com.android.systemui.shared.recents.model.Task) ObjectAnimator(android.animation.ObjectAnimator) AnimatorSet(android.animation.AnimatorSet) ValueAnimator(android.animation.ValueAnimator) DepthController(com.android.launcher3.statehandlers.DepthController) TextPaint(android.text.TextPaint) Point(android.graphics.Point)

Example 14 with PendingAnimation

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());
}
Also used : PendingAnimation(com.android.launcher3.anim.PendingAnimation) BaseQuickstepLauncher(com.android.launcher3.BaseQuickstepLauncher) StateAnimationConfig(com.android.launcher3.states.StateAnimationConfig) DepthController(com.android.launcher3.statehandlers.DepthController)

Example 15 with PendingAnimation

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);
}
Also used : PendingAnimation(com.android.launcher3.anim.PendingAnimation) AnimatorPlaybackController(com.android.launcher3.anim.AnimatorPlaybackController)

Aggregations

PendingAnimation (com.android.launcher3.anim.PendingAnimation)145 AnimatorPlaybackController (com.android.launcher3.anim.AnimatorPlaybackController)58 Animator (android.animation.Animator)46 AnimatorSet (android.animation.AnimatorSet)45 Rect (android.graphics.Rect)36 ValueAnimator (android.animation.ValueAnimator)34 Point (android.graphics.Point)32 TextPaint (android.text.TextPaint)32 ObjectAnimator (android.animation.ObjectAnimator)31 Context (android.content.Context)31 AnimatorListenerAdapter (android.animation.AnimatorListenerAdapter)29 View (android.view.View)29 RecentsView (com.android.quickstep.views.RecentsView)29 DeviceProfile (com.android.launcher3.DeviceProfile)27 RectF (android.graphics.RectF)26 Interpolator (android.view.animation.Interpolator)26 PagedOrientationHandler (com.android.launcher3.touch.PagedOrientationHandler)25 FloatProperty (android.util.FloatProperty)23 Matrix (android.graphics.Matrix)21 SpringProperty (com.android.launcher3.anim.SpringProperty)21