/** Render the animations for appearing and disappearing. */
  private void renderAnimations() {
    Keyframe kf0, kf1, kf2, kf3;
    float midwayPoint = 0.2f;
    int duration = 500;

    // Set up animator for disappearing.
    kf0 = Keyframe.ofFloat(0f, 1);
    kf1 = Keyframe.ofFloat(midwayPoint, mTransitionMidRadiusMultiplier);
    kf2 = Keyframe.ofFloat(1f, mTransitionEndRadiusMultiplier);
    PropertyValuesHolder radiusDisappear =
        PropertyValuesHolder.ofKeyframe("animationRadiusMultiplier", kf0, kf1, kf2);

    kf0 = Keyframe.ofFloat(0f, 1f);
    kf1 = Keyframe.ofFloat(1f, 0f);
    PropertyValuesHolder fadeOut = PropertyValuesHolder.ofKeyframe("alpha", kf0, kf1);

    mDisappearAnimator =
        ObjectAnimator.ofPropertyValuesHolder(
                AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : this,
                radiusDisappear,
                fadeOut)
            .setDuration(duration);
    mDisappearAnimator.addUpdateListener(mInvalidateUpdateListener);

    // Set up animator for reappearing.
    float delayMultiplier = 0.25f;
    float transitionDurationMultiplier = 1f;
    float totalDurationMultiplier = transitionDurationMultiplier + delayMultiplier;
    int totalDuration = (int) (duration * totalDurationMultiplier);
    float delayPoint = (delayMultiplier * duration) / totalDuration;
    midwayPoint = 1 - (midwayPoint * (1 - delayPoint));

    kf0 = Keyframe.ofFloat(0f, mTransitionEndRadiusMultiplier);
    kf1 = Keyframe.ofFloat(delayPoint, mTransitionEndRadiusMultiplier);
    kf2 = Keyframe.ofFloat(midwayPoint, mTransitionMidRadiusMultiplier);
    kf3 = Keyframe.ofFloat(1f, 1);
    PropertyValuesHolder radiusReappear =
        PropertyValuesHolder.ofKeyframe("animationRadiusMultiplier", kf0, kf1, kf2, kf3);

    kf0 = Keyframe.ofFloat(0f, 0f);
    kf1 = Keyframe.ofFloat(delayPoint, 0f);
    kf2 = Keyframe.ofFloat(1f, 1f);
    PropertyValuesHolder fadeIn = PropertyValuesHolder.ofKeyframe("alpha", kf0, kf1, kf2);

    mReappearAnimator =
        ObjectAnimator.ofPropertyValuesHolder(
                AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : this, radiusReappear, fadeIn)
            .setDuration(totalDuration);
    mReappearAnimator.addUpdateListener(mInvalidateUpdateListener);
  }
 /** Update the parallax based on the current slide offset. */
 @SuppressLint("NewApi")
 private void applyParallaxForCurrentSlideOffset() {
   if (mParallaxOffset > 0) {
     int mainViewOffset = getCurrentParalaxOffset();
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
       mMainView.setTranslationY(mainViewOffset);
     } else {
       AnimatorProxy.wrap(mMainView).setTranslationY(mainViewOffset);
     }
   }
 }
 @Override
 public void onFocusChange(View view, boolean gotFocus) {
   if (mFocusListener != null)
     mFocusListener.onFocusChange(FloatLabeledEditText.this, gotFocus);
   if (gotFocus && hintTextView.getVisibility() == VISIBLE) {
     ObjectAnimator.ofFloat(hintTextView, "alpha", 0.33f, 1f).start();
   } else if (hintTextView.getVisibility() == VISIBLE) {
     AnimatorProxy.wrap(hintTextView).setAlpha(1f); // Need this for compat reasons
     ObjectAnimator.ofFloat(hintTextView, "alpha", 1f, 0.33f).start();
   }
 }
  protected ObjectAnimator animateY(
      final View view, final float oldY, final float newY, final float durationUnit) {
    final int duration = getDuration(oldY, newY, durationUnit);

    final ObjectAnimator anim =
        ObjectAnimator.ofFloat(AnimatorProxy.wrap(view), "translationY", oldY - newY, 0);

    final int finalDuration = Math.min(Math.max(duration, MIN_ANIM_DURATION), MAX_ANIM_DURATION);

    anim.setDuration((long) (finalDuration * animationDurationFactor));
    anim.setInterpolator(translateInterpolater);

    return anim;
  }
  private void initialize() {
    setOrientation(VERTICAL);
    if (isInEditMode()) {
      return;
    }

    View view =
        LayoutInflater.from(mContext).inflate(R.layout.widget_float_labeled_edit_text, this);

    hintTextView = (TextView) view.findViewById(R.id.FloatLabeledEditTextHint);
    editText = (EditText) view.findViewById(R.id.FloatLabeledEditTextEditText);

    if (hint != null) {
      setHint(hint);
    }

    editText.setImeOptions(imeOptions);

    if (imeActionId > -1 && !TextUtils.isEmpty(imeActionLabel)) {
      editText.setImeActionLabel(imeActionLabel, imeActionId);
    }

    editText.setSingleLine(singleLine);
    hintTextView.setTextColor(hintColor != null ? hintColor : ColorStateList.valueOf(Color.BLACK));
    editText.setTextColor(textColor != null ? textColor : ColorStateList.valueOf(Color.BLACK));

    if (inputType != EditorInfo.TYPE_NULL) {
      editText.setInputType(inputType);
    }

    hintTextView.setVisibility(View.INVISIBLE);
    AnimatorProxy.wrap(hintTextView).setAlpha(0); // Need this for compat reasons
    editText.addTextChangedListener(onTextChanged);
    editText.setOnFocusChangeListener(onFocusChanged);

    editText.setOnClickListener(
        new OnClickListener() {
          @Override
          public void onClick(View v) {
            if (mClickListener != null) mClickListener.onClick(FloatLabeledEditText.this);
          }
        });
  }
 @Override
 public void setValue(View object, float value) {
   AnimatorProxy.wrap(object).setRotationY(value);
 }
 @Override
 public Float get(View object) {
   return AnimatorProxy.wrap(object).getRotationX();
 }
 @Override
 public Float get(View object) {
   return AnimatorProxy.wrap(object).getTranslationY();
 }
 @Override
 public Float get(View object) {
   return AnimatorProxy.wrap(object).getPivotY();
 }
 @Override
 public void setValue(View object, float value) {
   AnimatorProxy.wrap(object).setPivotX(value);
 }
 @Override
 public Integer get(View object) {
   return AnimatorProxy.wrap(object).getScrollY();
 }
 @Override
 public void setValue(View object, int value) {
   AnimatorProxy.wrap(object).setScrollY(value);
 }
  /** Animate items that are deleted entirely and items that move out of bounds. */
  private void animatePreLayout(
      final float durationUnit, final Animator.AnimatorListener listener) {
    final AnimatorSet animatorSet = new AnimatorSet();

    final int firstVisiblePosition = getFirstVisiblePosition();
    final int childCount = getChildCount();

    for (final Iterator<Entry<Long, Float>> iter = yMap.entrySet().iterator(); iter.hasNext(); ) {
      final Entry<Long, Float> entry = iter.next();

      final long id = entry.getKey();
      final int oldPos = positionMap.get(id);
      final View child = getChildAt(oldPos - firstVisiblePosition);
      final int newPos = getPositionForId(id);

      // fade out items that disappear
      if (newPos == -1) {
        final ObjectAnimator anim = animateAlpha(child, false);
        animatorSet.play(anim);

        iter.remove();
        positionMap.remove(id);
        continue;
      }

      // translate items that move out of bounds
      if (newPos < firstVisiblePosition || newPos > firstVisiblePosition + childCount) {
        final float offset;

        if (newPos < firstVisiblePosition) {
          offset = -getHeight();
        } else {
          offset = getHeight();
        }

        final AnimatorProxy proxy = AnimatorProxy.wrap(child);
        final ObjectAnimator anim = ObjectAnimator.ofFloat(proxy, "translationY", 0f, offset);

        final int finalDuration = getDuration(0, getHeight() / 2, durationUnit);

        anim.setInterpolator(new AccelerateInterpolator());
        anim.setDuration((long) (finalDuration * animationDurationFactor));

        animatorSet.addListener(
            new AnimatorListenerAdapter() {
              @Override
              public void onAnimationEnd(final Animator animation) {
                child.post(
                    new Runnable() {

                      @Override
                      public void run() {
                        proxy.setTranslationY(0f);
                      }
                    });
              }
            });
        animatorSet.play(anim);

        iter.remove();
        positionMap.remove(id);
        continue;
      }
    }

    if (!animatorSet.getChildAnimations().isEmpty()) {
      animatorSet.addListener(listener);
      animatorSet.start();
    } else {
      listener.onAnimationEnd(animatorSet);
    }
  }