1package android.support.v17.leanback.transition; 2 3import android.support.v17.leanback.R; 4 5import android.animation.Animator; 6import android.animation.AnimatorListenerAdapter; 7import android.animation.ObjectAnimator; 8import android.animation.TimeInterpolator; 9import android.graphics.Path; 10import android.transition.Transition; 11import android.transition.TransitionValues; 12import android.transition.Transition.TransitionListener; 13import android.view.View; 14 15/** 16 * This class is used by Slide and Explode to create an animator that goes from the start 17 * position to the end position. It takes into account the canceled position so that it 18 * will not blink out or shift suddenly when the transition is interrupted. 19 * @hide 20 */ 21class TranslationAnimationCreator { 22 23 /** 24 * Creates an animator that can be used for x and/or y translations. When interrupted, 25 * it sets a tag to keep track of the position so that it may be continued from position. 26 * 27 * @param view The view being moved. This may be in the overlay for onDisappear. 28 * @param values The values containing the view in the view hierarchy. 29 * @param viewPosX The x screen coordinate of view 30 * @param viewPosY The y screen coordinate of view 31 * @param startX The start translation x of view 32 * @param startY The start translation y of view 33 * @param endX The end translation x of view 34 * @param endY The end translation y of view 35 * @param interpolator The interpolator to use with this animator. 36 * @return An animator that moves from (startX, startY) to (endX, endY) unless there was 37 * a previous interruption, in which case it moves from the current position to (endX, endY). 38 */ 39 static Animator createAnimation(View view, TransitionValues values, int viewPosX, int viewPosY, 40 float startX, float startY, float endX, float endY, TimeInterpolator interpolator, 41 Transition transition) { 42 float terminalX = view.getTranslationX(); 43 float terminalY = view.getTranslationY(); 44 int[] startPosition = (int[]) values.view.getTag(R.id.transitionPosition); 45 if (startPosition != null) { 46 startX = startPosition[0] - viewPosX + terminalX; 47 startY = startPosition[1] - viewPosY + terminalY; 48 } 49 // Initial position is at translation startX, startY, so position is offset by that amount 50 int startPosX = viewPosX + Math.round(startX - terminalX); 51 int startPosY = viewPosY + Math.round(startY - terminalY); 52 53 view.setTranslationX(startX); 54 view.setTranslationY(startY); 55 if (startX == endX && startY == endY) { 56 return null; 57 } 58 Path path = new Path(); 59 path.moveTo(startX, startY); 60 path.lineTo(endX, endY); 61 ObjectAnimator anim = ObjectAnimator.ofFloat(view, View.TRANSLATION_X, View.TRANSLATION_Y, 62 path); 63 64 TransitionPositionListener listener = new TransitionPositionListener(view, values.view, 65 startPosX, startPosY, terminalX, terminalY); 66 transition.addListener(listener); 67 anim.addListener(listener); 68 anim.addPauseListener(listener); 69 anim.setInterpolator(interpolator); 70 return anim; 71 } 72 73 private static class TransitionPositionListener extends AnimatorListenerAdapter implements 74 TransitionListener { 75 76 private final View mViewInHierarchy; 77 private final View mMovingView; 78 private final int mStartX; 79 private final int mStartY; 80 private int[] mTransitionPosition; 81 private float mPausedX; 82 private float mPausedY; 83 private final float mTerminalX; 84 private final float mTerminalY; 85 86 private TransitionPositionListener(View movingView, View viewInHierarchy, 87 int startX, int startY, float terminalX, float terminalY) { 88 mMovingView = movingView; 89 mViewInHierarchy = viewInHierarchy; 90 mStartX = startX - Math.round(mMovingView.getTranslationX()); 91 mStartY = startY - Math.round(mMovingView.getTranslationY()); 92 mTerminalX = terminalX; 93 mTerminalY = terminalY; 94 mTransitionPosition = (int[]) mViewInHierarchy.getTag(R.id.transitionPosition); 95 if (mTransitionPosition != null) { 96 mViewInHierarchy.setTag(R.id.transitionPosition, null); 97 } 98 } 99 100 @Override 101 public void onAnimationCancel(Animator animation) { 102 if (mTransitionPosition == null) { 103 mTransitionPosition = new int[2]; 104 } 105 mTransitionPosition[0] = Math.round(mStartX + mMovingView.getTranslationX()); 106 mTransitionPosition[1] = Math.round(mStartY + mMovingView.getTranslationY()); 107 mViewInHierarchy.setTag(R.id.transitionPosition, mTransitionPosition); 108 } 109 110 @Override 111 public void onAnimationEnd(Animator animator) { 112 } 113 114 @Override 115 public void onAnimationPause(Animator animator) { 116 mPausedX = mMovingView.getTranslationX(); 117 mPausedY = mMovingView.getTranslationY(); 118 mMovingView.setTranslationX(mTerminalX); 119 mMovingView.setTranslationY(mTerminalY); 120 } 121 122 @Override 123 public void onAnimationResume(Animator animator) { 124 mMovingView.setTranslationX(mPausedX); 125 mMovingView.setTranslationY(mPausedY); 126 } 127 128 @Override 129 public void onTransitionStart(Transition transition) { 130 } 131 132 @Override 133 public void onTransitionEnd(Transition transition) { 134 mMovingView.setTranslationX(mTerminalX); 135 mMovingView.setTranslationY(mTerminalY); 136 } 137 138 @Override 139 public void onTransitionCancel(Transition transition) { 140 } 141 142 @Override 143 public void onTransitionPause(Transition transition) { 144 } 145 146 @Override 147 public void onTransitionResume(Transition transition) { 148 } 149 } 150 151} 152