Merge "Update status bar transition start time" into sc-qpr1-dev am: 5784ba0c38 am: 65e4e7d7fa am: 89f099b89d
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15879493 Change-Id: I1043c9026f3cb6d5aab883d475a4b1a116c2db53
This commit is contained in:
@@ -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.
|
||||
*
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,16 +125,30 @@ public class WindowAnimationSpec implements AnimationSpec {
|
||||
@Override
|
||||
public long calculateStatusBarTransitionStartTime() {
|
||||
TranslateAnimation openTranslateAnimation = findTranslateAnimation(mAnimation);
|
||||
if (openTranslateAnimation != null) {
|
||||
|
||||
// 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
|
||||
// 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;
|
||||
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 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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user