Example usage for android.animation Animator setStartDelay

List of usage examples for android.animation Animator setStartDelay

Introduction

In this page you can find the example usage for android.animation Animator setStartDelay.

Prototype

public abstract void setStartDelay(long startDelay);

Source Link

Document

The amount of time, in milliseconds, to delay processing the animation after #start() is called.

Usage

From source file:com.rbware.github.androidcouchpotato.app.OnboardingSupportFragment.java

boolean startLogoAnimation() {
    Animator animator = null;//from ww w.j a  v a  2 s .  c  om
    if (mLogoResourceId != 0) {
        mLogoView.setVisibility(View.VISIBLE);
        mLogoView.setImageResource(mLogoResourceId);
        Animator inAnimator = AnimatorInflater.loadAnimator(getActivity(), R.animator.lb_onboarding_logo_enter);
        Animator outAnimator = AnimatorInflater.loadAnimator(getActivity(), R.animator.lb_onboarding_logo_exit);
        outAnimator.setStartDelay(LOGO_SPLASH_PAUSE_DURATION_MS);
        AnimatorSet logoAnimator = new AnimatorSet();
        logoAnimator.playSequentially(inAnimator, outAnimator);
        logoAnimator.setTarget(mLogoView);
        animator = logoAnimator;
    } else {
        animator = onCreateLogoAnimation();
    }
    if (animator != null) {
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                if (getActivity() != null) {
                    startEnterAnimation();
                }
            }
        });
        animator.start();
        return true;
    }
    return false;
}

From source file:com.androidinspain.deskclock.timer.TimerFragment.java

/**
 * @param toView one of {@link #mTimersView} or {@link #mCreateTimerView}
 * @param timerToRemove the timer to be removed during the animation; {@code null} if no timer
 *      should be removed/*from  w w  w.ja v  a2  s  .com*/
 * @param animateDown {@code true} if the views should animate upwards, otherwise downwards
 */
private void animateToView(final View toView, final Timer timerToRemove, final boolean animateDown) {
    if (mCurrentView == toView) {
        return;
    }

    final boolean toTimers = toView == mTimersView;
    if (toTimers) {
        mTimersView.setVisibility(VISIBLE);
    } else {
        mCreateTimerView.setVisibility(VISIBLE);
    }
    // Avoid double-taps by enabling/disabling the set of buttons active on the new view.
    updateFab(BUTTONS_DISABLE);

    final long animationDuration = UiDataModel.getUiDataModel().getLongAnimationDuration();

    final ViewTreeObserver viewTreeObserver = toView.getViewTreeObserver();
    viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {
            if (viewTreeObserver.isAlive()) {
                viewTreeObserver.removeOnPreDrawListener(this);
            }

            final View view = mTimersView.findViewById(com.androidinspain.deskclock.R.id.timer_time);
            final float distanceY = view != null ? view.getHeight() + view.getY() : 0;
            final float translationDistance = animateDown ? distanceY : -distanceY;

            toView.setTranslationY(-translationDistance);
            mCurrentView.setTranslationY(0f);
            toView.setAlpha(0f);
            mCurrentView.setAlpha(1f);

            final Animator translateCurrent = ObjectAnimator.ofFloat(mCurrentView, TRANSLATION_Y,
                    translationDistance);
            final Animator translateNew = ObjectAnimator.ofFloat(toView, TRANSLATION_Y, 0f);
            final AnimatorSet translationAnimatorSet = new AnimatorSet();
            translationAnimatorSet.playTogether(translateCurrent, translateNew);
            translationAnimatorSet.setDuration(animationDuration);
            translationAnimatorSet.setInterpolator(AnimatorUtils.INTERPOLATOR_FAST_OUT_SLOW_IN);

            final Animator fadeOutAnimator = ObjectAnimator.ofFloat(mCurrentView, ALPHA, 0f);
            fadeOutAnimator.setDuration(animationDuration / 2);
            fadeOutAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    super.onAnimationStart(animation);

                    // The fade-out animation and fab-shrinking animation should run together.
                    updateFab(FAB_AND_BUTTONS_SHRINK);
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    if (toTimers) {
                        showTimersView(FAB_AND_BUTTONS_EXPAND);

                        // Reset the state of the create view.
                        mCreateTimerView.reset();
                    } else {
                        showCreateTimerView(FAB_AND_BUTTONS_EXPAND);
                    }

                    if (timerToRemove != null) {
                        DataModel.getDataModel().removeTimer(timerToRemove);
                        Events.sendTimerEvent(com.androidinspain.deskclock.R.string.action_delete,
                                com.androidinspain.deskclock.R.string.label_deskclock);
                    }

                    // Update the fab and button states now that the correct view is visible and
                    // before the animation to expand the fab and buttons starts.
                    updateFab(FAB_AND_BUTTONS_IMMEDIATE);
                }
            });

            final Animator fadeInAnimator = ObjectAnimator.ofFloat(toView, ALPHA, 1f);
            fadeInAnimator.setDuration(animationDuration / 2);
            fadeInAnimator.setStartDelay(animationDuration / 2);

            final AnimatorSet animatorSet = new AnimatorSet();
            animatorSet.playTogether(fadeOutAnimator, fadeInAnimator, translationAnimatorSet);
            animatorSet.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    mTimersView.setTranslationY(0f);
                    mCreateTimerView.setTranslationY(0f);
                    mTimersView.setAlpha(1f);
                    mCreateTimerView.setAlpha(1f);
                }
            });
            animatorSet.start();

            return true;
        }
    });
}

From source file:android.support.v17.leanback.app.OnboardingSupportFragment.java

private void startEnterAnimation() {
    mEnterTransitionFinished = true;//w ww .j a v a  2s  . c  o  m
    initializeViews(getView());
    List<Animator> animators = new ArrayList<>();
    Animator animator = AnimatorInflater.loadAnimator(getActivity(),
            R.animator.lb_onboarding_page_indicator_enter);
    animator.setTarget(getPageCount() <= 1 ? mStartButton : mPageIndicator);
    animators.add(animator);
    // Header title
    View view = getActivity().findViewById(R.id.title);
    view.setAlpha(0);
    animator = AnimatorInflater.loadAnimator(getActivity(), R.animator.lb_onboarding_title_enter);
    animator.setStartDelay(START_DELAY_TITLE_MS);
    animator.setTarget(view);
    animators.add(animator);
    // Header description
    view = getActivity().findViewById(R.id.description);
    view.setAlpha(0);
    animator = AnimatorInflater.loadAnimator(getActivity(), R.animator.lb_onboarding_description_enter);
    animator.setStartDelay(START_DELAY_DESCRIPTION_MS);
    animator.setTarget(view);
    animators.add(animator);
    // Customized animation by the inherited class.
    Animator customAnimator = onCreateEnterAnimation();
    if (customAnimator != null) {
        animators.add(customAnimator);
    }
    mAnimator = new AnimatorSet();
    mAnimator.playTogether(animators);
    mAnimator.start();
    // Search focus and give the focus to the appropriate child which has become visible.
    getView().requestFocus();
}

From source file:com.rbware.github.androidcouchpotato.app.OnboardingSupportFragment.java

void startEnterAnimation() {
    mEnterTransitionFinished = true;/* w  w w  .  j  a v a2  s .co  m*/
    initializeViews(getView());
    List<Animator> animators = new ArrayList<>();
    Animator animator = AnimatorInflater.loadAnimator(getActivity(),
            R.animator.lb_onboarding_page_indicator_enter);
    animator.setTarget(getPageCount() <= 1 ? mStartButton : mPageIndicator);
    animators.add(animator);
    // Header title
    View view = getActivity().findViewById(R.id.title);
    view.setAlpha(0);
    animator = AnimatorInflater.loadAnimator(getActivity(), R.animator.lb_onboarding_title_enter);
    animator.setStartDelay(START_DELAY_TITLE_MS);
    animator.setTarget(view);
    animators.add(animator);
    // Header description
    view = getActivity().findViewById(R.id.description);
    view.setAlpha(0);
    animator = AnimatorInflater.loadAnimator(getActivity(), R.animator.lb_onboarding_description_enter);
    animator.setStartDelay(START_DELAY_DESCRIPTION_MS);
    animator.setTarget(view);
    animators.add(animator);
    // Customized animation by the inherited class.
    Animator customAnimator = onCreateEnterAnimation();
    if (customAnimator != null) {
        animators.add(customAnimator);
    }
    mAnimator = new AnimatorSet();
    mAnimator.playTogether(animators);
    mAnimator.start();
    // Search focus and give the focus to the appropriate child which has become visible.
    getView().requestFocus();
}

From source file:com.androidinspain.deskclock.alarms.dataadapter.ExpandedAlarmViewHolder.java

private Animator createCollapsingAnimator(AlarmItemViewHolder newHolder, long duration) {
    arrow.setVisibility(View.INVISIBLE);
    clock.setVisibility(View.INVISIBLE);
    onOff.setVisibility(View.INVISIBLE);

    final boolean daysVisible = repeatDays.getVisibility() == View.VISIBLE;
    final int numberOfItems = countNumberOfItems();

    final View oldView = itemView;
    final View newView = newHolder.itemView;

    final Animator backgroundAnimator = ObjectAnimator.ofPropertyValuesHolder(oldView,
            PropertyValuesHolder.ofInt(AnimatorUtils.BACKGROUND_ALPHA, 255, 0));
    backgroundAnimator.setDuration(duration);

    final Animator boundsAnimator = AnimatorUtils.getBoundsAnimator(oldView, oldView, newView);
    boundsAnimator.setDuration(duration);
    boundsAnimator.setInterpolator(AnimatorUtils.INTERPOLATOR_FAST_OUT_SLOW_IN);

    final long shortDuration = (long) (duration * ANIM_SHORT_DURATION_MULTIPLIER);
    final Animator repeatAnimation = ObjectAnimator.ofFloat(repeat, View.ALPHA, 0f).setDuration(shortDuration);
    final Animator editLabelAnimation = ObjectAnimator.ofFloat(editLabel, View.ALPHA, 0f)
            .setDuration(shortDuration);
    final Animator repeatDaysAnimation = ObjectAnimator.ofFloat(repeatDays, View.ALPHA, 0f)
            .setDuration(shortDuration);
    final Animator vibrateAnimation = ObjectAnimator.ofFloat(vibrate, View.ALPHA, 0f)
            .setDuration(shortDuration);
    final Animator ringtoneAnimation = ObjectAnimator.ofFloat(ringtone, View.ALPHA, 0f)
            .setDuration(shortDuration);
    final Animator dismissAnimation = ObjectAnimator.ofFloat(preemptiveDismissButton, View.ALPHA, 0f)
            .setDuration(shortDuration);
    final Animator deleteAnimation = ObjectAnimator.ofFloat(delete, View.ALPHA, 0f).setDuration(shortDuration);
    final Animator hairLineAnimation = ObjectAnimator.ofFloat(hairLine, View.ALPHA, 0f)
            .setDuration(shortDuration);

    // Set the staggered delays; use the first portion (duration * (1 - 1/4 - 1/6)) of the time,
    // so that the final animation, with a duration of 1/4 the total duration, finishes exactly
    // before the collapsed holder begins expanding.
    long startDelay = 0L;
    final long delayIncrement = (long) (duration * ANIM_LONG_DELAY_INCREMENT_MULTIPLIER) / (numberOfItems - 1);
    deleteAnimation.setStartDelay(startDelay);
    if (preemptiveDismissButton.getVisibility() == View.VISIBLE) {
        startDelay += delayIncrement;/*from ww w . j  a v  a  2  s . c  om*/
        dismissAnimation.setStartDelay(startDelay);
    }
    hairLineAnimation.setStartDelay(startDelay);
    startDelay += delayIncrement;
    editLabelAnimation.setStartDelay(startDelay);
    startDelay += delayIncrement;
    vibrateAnimation.setStartDelay(startDelay);
    ringtoneAnimation.setStartDelay(startDelay);
    startDelay += delayIncrement;
    if (daysVisible) {
        repeatDaysAnimation.setStartDelay(startDelay);
        startDelay += delayIncrement;
    }
    repeatAnimation.setStartDelay(startDelay);

    final AnimatorSet animatorSet = new AnimatorSet();
    animatorSet.playTogether(backgroundAnimator, boundsAnimator, repeatAnimation, repeatDaysAnimation,
            vibrateAnimation, ringtoneAnimation, editLabelAnimation, deleteAnimation, hairLineAnimation,
            dismissAnimation);
    return animatorSet;
}

From source file:io.plaidapp.ui.DribbbleShot.java

/**
 * Animate in the title, description and author  can't do this in a content transition as they
 * are within the ListView so do it manually.  Also handle the FAB tanslation here so that it
 * plays nicely with #calculateFabPosition
 *///from  w w  w  . j  a v  a 2 s . c o m
private void enterAnimation(boolean isOrientationChange) {
    Interpolator interp = AnimationUtils.loadInterpolator(this, android.R.interpolator.fast_out_slow_in);
    int offset = title.getHeight();
    viewEnterAnimation(title, offset, interp);
    if (description.getVisibility() == View.VISIBLE) {
        offset *= 1.5f;
        viewEnterAnimation(description, offset, interp);
    }
    // animate the fab without touching the alpha as this is handled in the content transition
    offset *= 1.5f;
    float fabTransY = fab.getTranslationY();
    fab.setTranslationY(fabTransY + offset);
    fab.animate().translationY(fabTransY).setDuration(600).setInterpolator(interp).start();
    offset *= 1.5f;
    viewEnterAnimation(shotActions, offset, interp);
    offset *= 1.5f;
    viewEnterAnimation(playerName, offset, interp);
    viewEnterAnimation(playerAvatar, offset, interp);
    viewEnterAnimation(shotTimeAgo, offset, interp);
    back.animate().alpha(1f).setDuration(600).setInterpolator(interp).start();

    if (isOrientationChange) {
        // we rely on the window enter content transition to show the fab. This isn't run on
        // orientation changes so manually show it.
        Animator showFab = ObjectAnimator.ofPropertyValuesHolder(fab,
                PropertyValuesHolder.ofFloat(View.ALPHA, 0f, 1f),
                PropertyValuesHolder.ofFloat(View.SCALE_X, 0f, 1f),
                PropertyValuesHolder.ofFloat(View.SCALE_Y, 0f, 1f));
        showFab.setStartDelay(300L);
        showFab.setDuration(300L);
        showFab.setInterpolator(
                AnimationUtils.loadInterpolator(this, android.R.interpolator.linear_out_slow_in));
        showFab.start();
    }
}

From source file:com.sinyuk.jianyimaterial.widgets.FloatingToolbar.java

@TargetApi(21)
private void hideLollipopImpl() {
    int rootWidth = mRoot.getWidth();

    float controlX;

    if (mFabOriginalX > rootWidth / 2f) {
        controlX = mFabOriginalX * 0.98f;
    } else {/*ww w.j  a  v a 2s  .com*/
        controlX = mFabOriginalX * 1.02f;
    }

    final Path path = new Path();
    path.moveTo(mFab.getX(), mFab.getY());
    final float x2 = controlX;
    final float y2 = getY();
    path.quadTo(x2, y2, mFabOriginalX, mFabOriginalY + getTranslationY());
    ObjectAnimator anim = ObjectAnimator.ofFloat(mFab, View.X, View.Y, path);
    anim.setInterpolator(new AccelerateDecelerateInterpolator());
    anim.setDuration(FAB_UNMORPH_DURATION);
    anim.setStartDelay(FAB_UNMORPH_DELAY);
    anim.start();

    /**
     * Animate FAB elevation back to 6dp
     */
    anim = ObjectAnimator.ofFloat(mFab, View.TRANSLATION_Z, 0);
    anim.setInterpolator(new AccelerateDecelerateInterpolator());
    anim.setDuration(FAB_UNMORPH_DURATION);
    anim.setStartDelay(FAB_UNMORPH_DELAY);
    anim.start();

    /**
     * Restore alpha of FAB drawable
     */
    Drawable drawable = mFab.getDrawable();
    if (drawable != null) {
        anim = ObjectAnimator.ofPropertyValuesHolder(drawable, PropertyValuesHolder.ofInt("alpha", 255));
        anim.setInterpolator(new AccelerateDecelerateInterpolator());
        anim.setDuration(FAB_UNMORPH_DURATION);
        anim.setStartDelay(FAB_UNMORPH_DELAY);
        anim.start();
    }

    Animator toolbarReveal = ViewAnimationUtils.createCircularReveal(this, getWidth() / 2, getHeight() / 2,
            (float) (Math.hypot(getWidth() / 2, getHeight() / 2)), (float) mFab.getWidth() / 2f);

    toolbarReveal.setTarget(this);
    toolbarReveal.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            setVisibility(View.INVISIBLE);
            mFab.setVisibility(View.VISIBLE);
            mMorphing = false;
        }
    });
    toolbarReveal.setDuration(CIRCULAR_UNREVEAL_DURATION);
    toolbarReveal.setInterpolator(new AccelerateInterpolator());
    toolbarReveal.setStartDelay(CIRCULAR_UNREVEAL_DELAY);
    toolbarReveal.start();

    /**
     * Animate FloatingToolbar animation back to 6dp
     */
    anim = ObjectAnimator.ofFloat(this, View.TRANSLATION_Z, 0);
    anim.setDuration(CIRCULAR_UNREVEAL_DURATION);
    anim.setStartDelay(CIRCULAR_UNREVEAL_DELAY);
    anim.start();
}

From source file:io.plaidapp.core.ui.transitions.ReflowText.java

/**
 * Create Animators to transition each run of text from start to end position and size.
 *///from   w ww .j a  va 2s .co  m
@NonNull
private List<Animator> createRunAnimators(View view, ReflowData startData, ReflowData endData, Bitmap startText,
        Bitmap endText, List<Run> runs) {
    List<Animator> animators = new ArrayList<>(runs.size());
    int dx = startData.bounds.left - endData.bounds.left;
    int dy = startData.bounds.top - endData.bounds.top;
    long startDelay = 0L;
    // move text closest to the destination first i.e. loop forward or backward over the runs
    boolean upward = startData.bounds.centerY() > endData.bounds.centerY();
    boolean first = true;
    boolean lastRightward = true;
    LinearInterpolator linearInterpolator = new LinearInterpolator();

    for (int i = upward ? 0 : runs.size() - 1; ((upward && i < runs.size())
            || (!upward && i >= 0)); i += (upward ? 1 : -1)) {
        Run run = runs.get(i);

        // skip text runs which aren't visible in either state
        if (!run.startVisible && !run.endVisible)
            continue;

        // create & position the drawable which displays the run; add it to the overlay.
        SwitchDrawable drawable = new SwitchDrawable(startText, run.start, startData.textSize, endText, run.end,
                endData.textSize);
        drawable.setBounds(run.start.left + dx, run.start.top + dy, run.start.right + dx,
                run.start.bottom + dy);
        view.getOverlay().add(drawable);

        PropertyValuesHolder topLeft = PropertyValuesHolder.ofObject(SwitchDrawable.TOP_LEFT, null,
                getPathMotion().getPath(run.start.left + dx, run.start.top + dy, run.end.left, run.end.top));
        PropertyValuesHolder width = PropertyValuesHolder.ofInt(SwitchDrawable.WIDTH, run.start.width(),
                run.end.width());
        PropertyValuesHolder height = PropertyValuesHolder.ofInt(SwitchDrawable.HEIGHT, run.start.height(),
                run.end.height());
        // the progress property drives the switching behaviour
        PropertyValuesHolder progress = PropertyValuesHolder.ofFloat(SwitchDrawable.PROGRESS, 0f, 1f);
        Animator runAnim = ObjectAnimator.ofPropertyValuesHolder(drawable, topLeft, width, height, progress);

        boolean rightward = run.start.centerX() + dx < run.end.centerX();
        if ((run.startVisible && run.endVisible) && !first && rightward != lastRightward) {
            // increase the start delay (by a decreasing amount) for the next run
            // (if it's visible throughout) to stagger the movement and try to minimize overlaps
            startDelay += staggerDelay;
            staggerDelay *= STAGGER_DECAY;
        }
        lastRightward = rightward;
        first = false;

        runAnim.setStartDelay(startDelay);
        long animDuration = Math.max(minDuration, duration - (startDelay / 2));
        runAnim.setDuration(animDuration);
        animators.add(runAnim);

        if (run.startVisible != run.endVisible) {
            // if run is appearing/disappearing then fade it in/out
            ObjectAnimator fade = ObjectAnimator.ofInt(drawable, SwitchDrawable.ALPHA,
                    run.startVisible ? OPAQUE : TRANSPARENT, run.endVisible ? OPAQUE : TRANSPARENT);
            fade.setDuration((duration + startDelay) / 2);
            if (!run.startVisible) {
                drawable.setAlpha(TRANSPARENT);
                fade.setStartDelay((duration + startDelay) / 2);
            } else {
                fade.setStartDelay(startDelay);
            }
            animators.add(fade);
        } else {
            // slightly fade during transition to minimize movement
            ObjectAnimator fade = ObjectAnimator.ofInt(drawable, SwitchDrawable.ALPHA, OPAQUE,
                    OPACITY_MID_TRANSITION, OPAQUE);
            fade.setStartDelay(startDelay);
            fade.setDuration(duration + startDelay);
            fade.setInterpolator(linearInterpolator);
            animators.add(fade);
        }
    }
    return animators;
}

From source file:android.support.transition.TransitionPort.java

/**
 * This is a utility method used by subclasses to handle standard parts of
 * setting up and running an Animator: it sets the {@link #getDuration()
 * duration} and the {@link #getStartDelay() startDelay}, starts the
 * animation, and, when the animator ends, calls {@link #end()}.
 *
 * @param animator The Animator to be run during this transition.
 * @hide/*from w ww.  j a v  a  2s . com*/
 */
@RestrictTo(GROUP_ID)
protected void animate(Animator animator) {
    // TODO: maybe pass auto-end as a boolean parameter?
    if (animator == null) {
        end();
    } else {
        if (getDuration() >= 0) {
            animator.setDuration(getDuration());
        }
        if (getStartDelay() >= 0) {
            animator.setStartDelay(getStartDelay());
        }
        if (getInterpolator() != null) {
            animator.setInterpolator(getInterpolator());
        }
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                end();
                animation.removeListener(this);
            }
        });
        animator.start();
    }
}

From source file:com.android.launcher3.Folder.java

public void animateOpen() {
    if (!(getParent() instanceof DragLayer))
        return;//from  ww w. ja  va 2s .co m

    Animator openFolderAnim = null;
    final Runnable onCompleteRunnable;
    if (!Utilities.isLmpOrAbove()) {
        positionAndSizeAsIcon();
        centerAboutIcon();

        PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1);
        PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);
        PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);
        final ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(this, alpha, scaleX, scaleY);
        oa.setDuration(mExpandDuration);
        openFolderAnim = oa;

        setLayerType(LAYER_TYPE_HARDWARE, null);
        onCompleteRunnable = new Runnable() {
            @Override
            public void run() {
                setLayerType(LAYER_TYPE_NONE, null);
            }
        };
    } else {
        prepareReveal();
        centerAboutIcon();

        int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
        int height = getFolderHeight();

        float transX = -0.075f * (width / 2 - getPivotX());
        float transY = -0.075f * (height / 2 - getPivotY());
        setTranslationX(transX);
        setTranslationY(transY);
        PropertyValuesHolder tx = PropertyValuesHolder.ofFloat("translationX", transX, 0);
        PropertyValuesHolder ty = PropertyValuesHolder.ofFloat("translationY", transY, 0);

        int rx = (int) Math.max(Math.max(width - getPivotX(), 0), getPivotX());
        int ry = (int) Math.max(Math.max(height - getPivotY(), 0), getPivotY());
        float radius = (float) Math.sqrt(rx * rx + ry * ry);
        AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
        Animator reveal = LauncherAnimUtils.createCircularReveal(this, (int) getPivotX(), (int) getPivotY(), 0,
                radius);
        reveal.setDuration(mMaterialExpandDuration);
        reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));

        mContent.setAlpha(0f);
        Animator iconsAlpha = LauncherAnimUtils.ofFloat(mContent, "alpha", 0f, 1f);
        iconsAlpha.setDuration(mMaterialExpandDuration);
        iconsAlpha.setStartDelay(mMaterialExpandStagger);
        iconsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));

        mFolderName.setAlpha(0f);
        Animator textAlpha = LauncherAnimUtils.ofFloat(mFolderName, "alpha", 0f, 1f);
        textAlpha.setDuration(mMaterialExpandDuration);
        textAlpha.setStartDelay(mMaterialExpandStagger);
        textAlpha.setInterpolator(new AccelerateInterpolator(1.5f));

        Animator drift = LauncherAnimUtils.ofPropertyValuesHolder(this, tx, ty);
        drift.setDuration(mMaterialExpandDuration);
        drift.setStartDelay(mMaterialExpandStagger);
        drift.setInterpolator(new LogDecelerateInterpolator(60, 0));

        anim.play(drift);
        anim.play(iconsAlpha);
        anim.play(textAlpha);
        anim.play(reveal);

        openFolderAnim = anim;

        mContent.setLayerType(LAYER_TYPE_HARDWARE, null);
        onCompleteRunnable = new Runnable() {
            @Override
            public void run() {
                mContent.setLayerType(LAYER_TYPE_NONE, null);
            }
        };
    }
    openFolderAnim.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationStart(Animator animation) {
            sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
                    String.format(getContext().getString(R.string.folder_opened), mContent.getCountX(),
                            mContent.getCountY()));
            mState = STATE_ANIMATING;
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            mState = STATE_OPEN;

            if (onCompleteRunnable != null) {
                onCompleteRunnable.run();
            }

            setFocusOnFirstChild();
        }
    });
    openFolderAnim.start();

    // Make sure the folder picks up the last drag move even if the finger doesn't move.
    if (mDragController.isDragging()) {
        mDragController.forceTouchMove();
    }
}