Merge "Update status bar transition start time" into sc-qpr1-dev
This commit is contained in:
@@ -57,6 +57,9 @@ public class TranslateAnimation extends Animation {
|
|||||||
/** @hide */
|
/** @hide */
|
||||||
protected float mToYDelta;
|
protected float mToYDelta;
|
||||||
|
|
||||||
|
private int mWidth;
|
||||||
|
private int mParentWidth;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor used when a TranslateAnimation is loaded from a resource.
|
* Constructor used when a TranslateAnimation is loaded from a resource.
|
||||||
*
|
*
|
||||||
@@ -179,5 +182,60 @@ public class TranslateAnimation extends Animation {
|
|||||||
mToXDelta = resolveSize(mToXType, mToXValue, width, parentWidth);
|
mToXDelta = resolveSize(mToXType, mToXValue, width, parentWidth);
|
||||||
mFromYDelta = resolveSize(mFromYType, mFromYValue, height, parentHeight);
|
mFromYDelta = resolveSize(mFromYType, mFromYValue, height, parentHeight);
|
||||||
mToYDelta = resolveSize(mToYType, mToYValue, 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,16 +125,30 @@ public class WindowAnimationSpec implements AnimationSpec {
|
|||||||
@Override
|
@Override
|
||||||
public long calculateStatusBarTransitionStartTime() {
|
public long calculateStatusBarTransitionStartTime() {
|
||||||
TranslateAnimation openTranslateAnimation = findTranslateAnimation(mAnimation);
|
TranslateAnimation openTranslateAnimation = findTranslateAnimation(mAnimation);
|
||||||
if (openTranslateAnimation != null) {
|
|
||||||
|
|
||||||
// Some interpolators are extremely quickly mostly finished, but not completely. For
|
if (openTranslateAnimation != null) {
|
||||||
// our purposes, we need to find the fraction for which ther interpolator is mostly
|
if (openTranslateAnimation.isXAxisTransition()
|
||||||
// there, and use that value for the calculation.
|
&& openTranslateAnimation.isFullWidthTranslate()) {
|
||||||
float t = findAlmostThereFraction(openTranslateAnimation.getInterpolator());
|
// On X axis transitions that are fullscreen (heuristic for task like transitions)
|
||||||
return SystemClock.uptimeMillis()
|
// we want the status bar to animate right in the middle of the translation when
|
||||||
+ openTranslateAnimation.getStartOffset()
|
// the windows/tasks have each moved half way across.
|
||||||
+ (long)(openTranslateAnimation.getDuration() * t)
|
float t = findMiddleOfTranslationFraction(openTranslateAnimation.getInterpolator());
|
||||||
- STATUS_BAR_TRANSITION_DURATION;
|
|
||||||
|
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 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 {
|
} else {
|
||||||
return SystemClock.uptimeMillis();
|
return SystemClock.uptimeMillis();
|
||||||
}
|
}
|
||||||
@@ -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
|
* Finds the fraction of the animation's duration at which the transition is almost done with a
|
||||||
* {@code interpolator(t + eps) > 0.99}.
|
* maximal error of 0.01 when it is animated with {@code interpolator}.
|
||||||
*/
|
*/
|
||||||
private static float findAlmostThereFraction(Interpolator 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 val = 0.5f;
|
||||||
float adj = 0.25f;
|
float adj = 0.25f;
|
||||||
while (adj >= 0.01f) {
|
|
||||||
if (interpolator.getInterpolation(val) < 0.99f) {
|
while (adj >= epsilon) {
|
||||||
|
if (interpolator.getInterpolation(val) < target) {
|
||||||
val += adj;
|
val += adj;
|
||||||
} else {
|
} else {
|
||||||
val -= adj;
|
val -= adj;
|
||||||
}
|
}
|
||||||
adj /= 2;
|
adj /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user