content: /*
   * Copyright (C) 2014 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package android.transition;
  
  import android.animation.Animator;
  import android.animation.AnimatorListenerAdapter;
  import android.animation.ObjectAnimator;
  import android.animation.TimeInterpolator;
  import android.graphics.Path;
  import android.transition.Transition.TransitionListener;
  import android.view.View;
  
  import com.android.internal.R;
  
  /**
   * This class is used by Slide and Explode to create an animator that goes from the start
   * position to the end position. It takes into account the canceled position so that it
   * will not blink out or shift suddenly when the transition is interrupted.
   */
  class TranslationAnimationCreator {
  
      /**
       * Creates an animator that can be used for x and/or y translations. When interrupted,
       * it sets a tag to keep track of the position so that it may be continued from position.
       *
       * @param view The view being moved. This may be in the overlay for onDisappear.
       * @param values The values containing the view in the view hierarchy.
       * @param viewPosX The x screen coordinate of view
       * @param viewPosY The y screen coordinate of view
       * @param startX The start translation x of view
       * @param startY The start translation y of view
       * @param endX The end translation x of view
       * @param endY The end translation y of view
       * @param interpolator The interpolator to use with this animator.
       * @return An animator that moves from (startX, startY) to (endX, endY) unless there was
       * a previous interruption, in which case it moves from the current position to (endX, endY).
       */
      static Animator createAnimation(View view, TransitionValues values, int viewPosX, int viewPosY,
              float startX, float startY, float endX, float endY, TimeInterpolator interpolator,
              Transition transition) {
          float terminalX = view.getTranslationX();
          float terminalY = view.getTranslationY();
          int[] startPosition = (int[]) values.view.getTag(R.id.transitionPosition);
          if (startPosition != null) {
              startX = startPosition[0] - viewPosX + terminalX;
              startY = startPosition[1] - viewPosY + terminalY;
          }
          // Initial position is at translation startX, startY, so position is offset by that amount
          int startPosX = viewPosX + Math.round(startX - terminalX);
          int startPosY = viewPosY + Math.round(startY - terminalY);
  
          view.setTranslationX(startX);
          view.setTranslationY(startY);
          if (startX == endX && startY == endY) {
              return null;
          }
          Path path = new Path();
          path.moveTo(startX, startY);
          path.lineTo(endX, endY);
          ObjectAnimator anim = ObjectAnimator.ofFloat(view, View.TRANSLATION_X, View.TRANSLATION_Y,
                  path);
  
          TransitionPositionListener listener = new TransitionPositionListener(view, values.view,
                  startPosX, startPosY, terminalX, terminalY);
          transition.addListener(listener);
          anim.addListener(listener);
          anim.addPauseListener(listener);
          anim.setInterpolator(interpolator);
          return anim;
      }
  
      private static class TransitionPositionListener extends AnimatorListenerAdapter implements
              TransitionListener {
  
          private final View mViewInHierarchy;
          private final View mMovingView;
          private final int mStartX;
          private final int mStartY;
          private int[] mTransitionPosition;
          private float mPausedX;
          private float mPausedY;
          private final float mTerminalX;
          private final float mTerminalY;
  
          private TransitionPositionListener(View movingView, View viewInHierarchy,
                  int startX, int startY, float terminalX, float terminalY) {
              mMovingView = movingView;
              mViewInHierarchy = viewInHierarchy;
              mStartX = startX - Math.round(mMovingView.getTranslationX());
              mStartY = startY - Math.round(mMovingView.getTranslationY());
              mTerminalX = terminalX;
              mTerminalY = terminalY;
              mTransitionPosition = (int[]) mViewInHierarchy.getTag(R.id.transitionPosition);
              if (mTransitionPosition != null) {
                  mViewInHierarchy.setTagInternal(R.id.transitionPosition, null);
              }
          }
  
          @Override
          public void onAnimationCancel(Animator animation) {
              if (mTransitionPosition == null) {
                  mTransitionPosition = new int[2];
              }
              mTransitionPosition[0] = Math.round(mStartX + mMovingView.getTranslationX());
              mTransitionPosition[1] = Math.round(mStartY + mMovingView.getTranslationY());
              mViewInHierarchy.setTagInternal(R.id.transitionPosition, mTransitionPosition);
          }
  
          @Override
          public void onAnimationEnd(Animator animator) {
          }
  
          @Override
          public void onAnimationPause(Animator animator) {
              mPausedX = mMovingView.getTranslationX();
              mPausedY = mMovingView.getTranslationY();
              mMovingView.setTranslationX(mTerminalX);
              mMovingView.setTranslationY(mTerminalY);
          }
  
          @Override
          public void onAnimationResume(Animator animator) {
              mMovingView.setTranslationX(mPausedX);
              mMovingView.setTranslationY(mPausedY);
          }
  
          @Override
          public void onTransitionStart(Transition transition) {
          }
  
          @Override
          public void onTransitionEnd(Transition transition) {
              mMovingView.setTranslationX(mTerminalX);
              mMovingView.setTranslationY(mTerminalY);
              transition.removeListener(this);
          }
  
          @Override
          public void onTransitionCancel(Transition transition) {
          }
  
          @Override
          public void onTransitionPause(Transition transition) {
          }
  
          @Override
          public void onTransitionResume(Transition transition) {
          }
      }
  
  }
  