private void contractPreLollipop(int x, int y, float startRadius, float endRadius) {

    final SupportAnimator toolbarContractAnim =
        io.codetail.animation.ViewAnimationUtils.createCircularReveal(
            mFabExpandLayout, x, y, startRadius, endRadius);
    toolbarContractAnim.setDuration(endAnimationDuration);

    toolbarContractAnim.addListener(
        new SupportAnimator.AnimatorListener() {
          @Override
          public void onAnimationStart() {}

          @Override
          public void onAnimationEnd() {
            contractAnimationEnd();
          }

          @Override
          public void onAnimationCancel() {}

          @Override
          public void onAnimationRepeat() {}
        });

    toolbarContractAnim.start();
  }
  private void revealTray(boolean reverse) {
    View sourceView = mFab;
    mTray.setVisibility(View.VISIBLE);

    final SupportAnimator revealAnimator;
    final int[] clearLocation = new int[2];
    sourceView.getLocationInWindow(clearLocation);
    clearLocation[0] += sourceView.getWidth() / 2;
    clearLocation[1] += sourceView.getHeight() / 2;
    final int revealCenterX = clearLocation[0] - mTray.getLeft();
    final int revealCenterY = clearLocation[1] - mTray.getTop();
    final double x1_2 = Math.pow(mTray.getLeft() - revealCenterX, 2);
    final double x2_2 = Math.pow(mTray.getRight() - revealCenterX, 2);
    final double y_2 = Math.pow(mTray.getTop() - revealCenterY, 2);
    final float revealRadius = (float) Math.max(Math.sqrt(x1_2 + y_2), Math.sqrt(x2_2 + y_2));

    float start = reverse ? revealRadius : 0;
    float end = reverse ? 0 : revealRadius;
    if (android.os.Build.VERSION.SDK_INT >= 21) {
      // The lollipop reveal uses local cords, so use tray height / 2
      revealAnimator =
          ViewAnimationUtils.createCircularReveal(
              mTray, revealCenterX, mTray.getHeight() / 2, start, end);
    } else {
      // The legacy support doesn't work with gravity bottom, so use the global cords
      revealAnimator =
          ViewAnimationUtils.createCircularReveal(mTray, revealCenterX, revealCenterY, start, end);
    }
    revealAnimator.setDuration(getResources().getInteger(android.R.integer.config_shortAnimTime));
    if (reverse) {
      revealAnimator.addListener(
          new AnimationFinishedListener() {
            @Override
            public void onAnimationFinished() {
              mTray.setVisibility(View.INVISIBLE);
            }
          });
    }
    play(revealAnimator);
  }
  public void show() {
    // stop all animations!
    mContent.clearAnimation();

    setVisibility(VISIBLE);
    int right = mContent.getRight();
    int top = mContent.getTop();
    float f =
        (float) Math.sqrt(Math.pow(mContent.getWidth(), 2D) + Math.pow(mContent.getHeight(), 2D));
    SupportAnimator showAnimator =
        ViewAnimationUtils.createCircularReveal(mContent, right, top, 0, f);
    setAnimatorParams(showAnimator);
    showAnimator.addListener(
        new SupportAnimator.AnimatorListener() {
          @Override
          public void onAnimationStart() {}

          @Override
          public void onAnimationEnd() {}

          @Override
          public void onAnimationCancel() {}

          @Override
          public void onAnimationRepeat() {}
        });

    // create hide animation now
    mHideAnimator = showAnimator.reverse();
    setAnimatorParams(mHideAnimator);
    mHideAnimator.addListener(
        new SupportAnimator.AnimatorListener() {
          @Override
          public void onAnimationStart() {}

          @Override
          public void onAnimationEnd() {
            hideNow();
          }

          @Override
          public void onAnimationCancel() {}

          @Override
          public void onAnimationRepeat() {}
        });

    showAnimator.start();
  }
  private void reveal(View sourceView, int colorRes, final AnimatorListener listener) {
    // Make reveal cover the display
    final RevealView revealView = new RevealView(this);
    revealView.setLayoutParams(mLayoutParams);
    revealView.setRevealColor(getResources().getColor(colorRes));
    mDisplayForeground.addView(revealView);

    final SupportAnimator revealAnimator;
    final int[] clearLocation = new int[2];
    if (sourceView != null) {
      sourceView.getLocationInWindow(clearLocation);
      clearLocation[0] += sourceView.getWidth() / 2;
      clearLocation[1] += sourceView.getHeight() / 2;
    } else {
      clearLocation[0] = mDisplayForeground.getWidth() / 2;
      clearLocation[1] = mDisplayForeground.getHeight() / 2;
    }
    final int revealCenterX = clearLocation[0] - revealView.getLeft();
    final int revealCenterY = clearLocation[1] - revealView.getTop();
    final double x1_2 = Math.pow(revealView.getLeft() - revealCenterX, 2);
    final double x2_2 = Math.pow(revealView.getRight() - revealCenterX, 2);
    final double y_2 = Math.pow(revealView.getTop() - revealCenterY, 2);
    final float revealRadius = (float) Math.max(Math.sqrt(x1_2 + y_2), Math.sqrt(x2_2 + y_2));

    revealAnimator =
        ViewAnimationUtils.createCircularReveal(
            revealView, revealCenterX, revealCenterY, 0.0f, revealRadius);
    revealAnimator.setDuration(getResources().getInteger(android.R.integer.config_longAnimTime));
    revealAnimator.addListener(listener);

    final Animator alphaAnimator = ObjectAnimator.ofFloat(revealView, View.ALPHA, 0.0f);
    alphaAnimator.setDuration(getResources().getInteger(android.R.integer.config_mediumAnimTime));
    alphaAnimator.addListener(
        new AnimationFinishedListener() {
          @Override
          public void onAnimationFinished() {
            mDisplayForeground.removeView(revealView);
          }
        });

    revealAnimator.addListener(
        new AnimationFinishedListener() {
          @Override
          public void onAnimationFinished() {
            play(alphaAnimator);
          }
        });
    play(revealAnimator);
  }
  public void startCircularReveal() {

    // get the final radius for the clipping circle
    int finalRadius =
        Math.max(mRlReveal.getWidth(), mRlReveal.getHeight()) + mRlReveal.getHeight() / 2;
    // bottom or top
    int y = UIUtil.getRevealDirection(mRlReveal, mConfigSplash.getRevealFlagY());
    // left or right
    int x = UIUtil.getRevealDirection(mRlReveal, mConfigSplash.getRevealFlagX());

    mRlReveal.setBackgroundColor(getResources().getColor(mConfigSplash.getBackgroundColor()));
    SupportAnimator animator =
        ViewAnimationUtils.createCircularReveal(mRlReveal, x, y, 0, finalRadius);
    animator.setInterpolator(new AccelerateDecelerateInterpolator());
    animator.setDuration(mConfigSplash.getAnimCircularRevealDuration());
    animator.addListener(
        new SupportAnimator.AnimatorListener() {
          @Override
          public void onAnimationStart() {}

          @Override
          public void onAnimationCancel() {}

          @Override
          public void onAnimationRepeat() {}

          @Override
          public void onAnimationEnd() {

            if (pathOrLogo == Flags.WITH_PATH) {
              mPathLogo.start();
            } else {
              startLogoAnimation();
            }
          }
        });
    animator.start();
    hasAnimationStarted = true;
  }
  @SuppressLint("NewApi")
  private void createReveal(final View myView) {

    // get the center for the clipping circle
    int cx = (myView.getWidth()) / 2;
    int cy = (myView.getHeight()) / 2;

    // get the final radius for the clipping circle
    int finalRadius = Math.max(myView.getWidth(), myView.getHeight());

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
      Animator animator =
          android.view.ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
      animator.setDuration(800);
      animator.start();
    } else {
      SupportAnimator animator =
          ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
      animator.setInterpolator(new AccelerateDecelerateInterpolator());
      animator.setDuration(800);
      animator.start();
    }
  }