Loading core/java/android/view/animation/TranslateAnimation.java +58 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,9 @@ public class TranslateAnimation extends Animation { /** @hide */ protected float mToYDelta; private int mWidth; private int mParentWidth; /** * Constructor used when a TranslateAnimation is loaded from a resource. * Loading Loading @@ -179,5 +182,60 @@ public class TranslateAnimation extends Animation { mToXDelta = resolveSize(mToXType, mToXValue, width, parentWidth); mFromYDelta = resolveSize(mFromYType, mFromYValue, height, parentHeight); mToYDelta = resolveSize(mToYType, mToYValue, height, parentHeight); mWidth = width; mParentWidth = parentWidth; } /** * Checks whether or not the translation is exclusively an x axis translation. * * @hide */ public boolean isXAxisTransition() { return mFromXDelta - mToXDelta != 0 && mFromYDelta - mToYDelta == 0; } /** * Checks whether or not the translation is a full width x axis slide in or out translation. * * @hide */ public boolean isFullWidthTranslate() { boolean isXAxisSlideTransition = isSlideInLeft() || isSlideOutRight() || isSlideInRight() || isSlideOutLeft(); return mWidth == mParentWidth && isXAxisSlideTransition; } private boolean isSlideInLeft() { boolean startsOutOfParentOnLeft = mFromXDelta <= -mWidth; return startsOutOfParentOnLeft && endsXEnclosedWithinParent(); } private boolean isSlideOutRight() { boolean endOutOfParentOnRight = mToXDelta >= mParentWidth; return startsXEnclosedWithinParent() && endOutOfParentOnRight; } private boolean isSlideInRight() { boolean startsOutOfParentOnRight = mFromXDelta >= mParentWidth; return startsOutOfParentOnRight && endsXEnclosedWithinParent(); } private boolean isSlideOutLeft() { boolean endOutOfParentOnLeft = mToXDelta <= -mWidth; return startsXEnclosedWithinParent() && endOutOfParentOnLeft; } private boolean endsXEnclosedWithinParent() { return mWidth <= mParentWidth && mToXDelta + mWidth <= mParentWidth && mToXDelta >= 0; } private boolean startsXEnclosedWithinParent() { return mWidth <= mParentWidth && mFromXDelta + mWidth <= mParentWidth && mFromXDelta >= 0; } } services/core/java/com/android/server/wm/WindowAnimationSpec.java +46 −13 Original line number Diff line number Diff line Loading @@ -125,16 +125,30 @@ public class WindowAnimationSpec implements AnimationSpec { @Override public long calculateStatusBarTransitionStartTime() { TranslateAnimation openTranslateAnimation = findTranslateAnimation(mAnimation); if (openTranslateAnimation != null) { if (openTranslateAnimation.isXAxisTransition() && openTranslateAnimation.isFullWidthTranslate()) { // On X axis transitions that are fullscreen (heuristic for task like transitions) // we want the status bar to animate right in the middle of the translation when // the windows/tasks have each moved half way across. float t = findMiddleOfTranslationFraction(openTranslateAnimation.getInterpolator()); return SystemClock.uptimeMillis() + openTranslateAnimation.getStartOffset() + (long) (openTranslateAnimation.getDuration() * t) - (long) (STATUS_BAR_TRANSITION_DURATION * 0.5); } else { // Some interpolators are extremely quickly mostly finished, but not completely. For // our purposes, we need to find the fraction for which ther interpolator is mostly // our purposes, we need to find the fraction for which their interpolator is mostly // there, and use that value for the calculation. float t = findAlmostThereFraction(openTranslateAnimation.getInterpolator()); return SystemClock.uptimeMillis() + openTranslateAnimation.getStartOffset() + (long) (openTranslateAnimation.getDuration() * t) - STATUS_BAR_TRANSITION_DURATION; } } else { return SystemClock.uptimeMillis(); } Loading Loading @@ -183,20 +197,39 @@ public class WindowAnimationSpec implements AnimationSpec { } /** * Binary searches for a {@code t} such that there exists a {@code -0.01 < eps < 0.01} for which * {@code interpolator(t + eps) > 0.99}. * Finds the fraction of the animation's duration at which the transition is almost done with a * maximal error of 0.01 when it is animated with {@code interpolator}. */ private static float findAlmostThereFraction(Interpolator interpolator) { return findInterpolationAdjustedTargetFraction(interpolator, 0.99f, 0.01f); } /** * Finds the fraction of the animation's duration at which the transition is spacially half way * done with a maximal error of 0.01 when it is animated with {@code interpolator}. */ private float findMiddleOfTranslationFraction(Interpolator interpolator) { return findInterpolationAdjustedTargetFraction(interpolator, 0.5f, 0.01f); } /** * Binary searches for a {@code val} such that there exists an {@code -0.01 < epsilon < 0.01} * for which {@code interpolator(val + epsilon) > target}. */ private static float findInterpolationAdjustedTargetFraction( Interpolator interpolator, float target, float epsilon) { float val = 0.5f; float adj = 0.25f; while (adj >= 0.01f) { if (interpolator.getInterpolation(val) < 0.99f) { while (adj >= epsilon) { if (interpolator.getInterpolation(val) < target) { val += adj; } else { val -= adj; } adj /= 2; } return val; } Loading Loading
core/java/android/view/animation/TranslateAnimation.java +58 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,9 @@ public class TranslateAnimation extends Animation { /** @hide */ protected float mToYDelta; private int mWidth; private int mParentWidth; /** * Constructor used when a TranslateAnimation is loaded from a resource. * Loading Loading @@ -179,5 +182,60 @@ public class TranslateAnimation extends Animation { mToXDelta = resolveSize(mToXType, mToXValue, width, parentWidth); mFromYDelta = resolveSize(mFromYType, mFromYValue, height, parentHeight); mToYDelta = resolveSize(mToYType, mToYValue, height, parentHeight); mWidth = width; mParentWidth = parentWidth; } /** * Checks whether or not the translation is exclusively an x axis translation. * * @hide */ public boolean isXAxisTransition() { return mFromXDelta - mToXDelta != 0 && mFromYDelta - mToYDelta == 0; } /** * Checks whether or not the translation is a full width x axis slide in or out translation. * * @hide */ public boolean isFullWidthTranslate() { boolean isXAxisSlideTransition = isSlideInLeft() || isSlideOutRight() || isSlideInRight() || isSlideOutLeft(); return mWidth == mParentWidth && isXAxisSlideTransition; } private boolean isSlideInLeft() { boolean startsOutOfParentOnLeft = mFromXDelta <= -mWidth; return startsOutOfParentOnLeft && endsXEnclosedWithinParent(); } private boolean isSlideOutRight() { boolean endOutOfParentOnRight = mToXDelta >= mParentWidth; return startsXEnclosedWithinParent() && endOutOfParentOnRight; } private boolean isSlideInRight() { boolean startsOutOfParentOnRight = mFromXDelta >= mParentWidth; return startsOutOfParentOnRight && endsXEnclosedWithinParent(); } private boolean isSlideOutLeft() { boolean endOutOfParentOnLeft = mToXDelta <= -mWidth; return startsXEnclosedWithinParent() && endOutOfParentOnLeft; } private boolean endsXEnclosedWithinParent() { return mWidth <= mParentWidth && mToXDelta + mWidth <= mParentWidth && mToXDelta >= 0; } private boolean startsXEnclosedWithinParent() { return mWidth <= mParentWidth && mFromXDelta + mWidth <= mParentWidth && mFromXDelta >= 0; } }
services/core/java/com/android/server/wm/WindowAnimationSpec.java +46 −13 Original line number Diff line number Diff line Loading @@ -125,16 +125,30 @@ public class WindowAnimationSpec implements AnimationSpec { @Override public long calculateStatusBarTransitionStartTime() { TranslateAnimation openTranslateAnimation = findTranslateAnimation(mAnimation); if (openTranslateAnimation != null) { if (openTranslateAnimation.isXAxisTransition() && openTranslateAnimation.isFullWidthTranslate()) { // On X axis transitions that are fullscreen (heuristic for task like transitions) // we want the status bar to animate right in the middle of the translation when // the windows/tasks have each moved half way across. float t = findMiddleOfTranslationFraction(openTranslateAnimation.getInterpolator()); return SystemClock.uptimeMillis() + openTranslateAnimation.getStartOffset() + (long) (openTranslateAnimation.getDuration() * t) - (long) (STATUS_BAR_TRANSITION_DURATION * 0.5); } else { // Some interpolators are extremely quickly mostly finished, but not completely. For // our purposes, we need to find the fraction for which ther interpolator is mostly // our purposes, we need to find the fraction for which their interpolator is mostly // there, and use that value for the calculation. float t = findAlmostThereFraction(openTranslateAnimation.getInterpolator()); return SystemClock.uptimeMillis() + openTranslateAnimation.getStartOffset() + (long) (openTranslateAnimation.getDuration() * t) - STATUS_BAR_TRANSITION_DURATION; } } else { return SystemClock.uptimeMillis(); } Loading Loading @@ -183,20 +197,39 @@ public class WindowAnimationSpec implements AnimationSpec { } /** * Binary searches for a {@code t} such that there exists a {@code -0.01 < eps < 0.01} for which * {@code interpolator(t + eps) > 0.99}. * Finds the fraction of the animation's duration at which the transition is almost done with a * maximal error of 0.01 when it is animated with {@code interpolator}. */ private static float findAlmostThereFraction(Interpolator interpolator) { return findInterpolationAdjustedTargetFraction(interpolator, 0.99f, 0.01f); } /** * Finds the fraction of the animation's duration at which the transition is spacially half way * done with a maximal error of 0.01 when it is animated with {@code interpolator}. */ private float findMiddleOfTranslationFraction(Interpolator interpolator) { return findInterpolationAdjustedTargetFraction(interpolator, 0.5f, 0.01f); } /** * Binary searches for a {@code val} such that there exists an {@code -0.01 < epsilon < 0.01} * for which {@code interpolator(val + epsilon) > target}. */ private static float findInterpolationAdjustedTargetFraction( Interpolator interpolator, float target, float epsilon) { float val = 0.5f; float adj = 0.25f; while (adj >= 0.01f) { if (interpolator.getInterpolation(val) < 0.99f) { while (adj >= epsilon) { if (interpolator.getInterpolation(val) < target) { val += adj; } else { val -= adj; } adj /= 2; } return val; } Loading