Use fastOutSlowIn curve for transitions on iOS when not controlled by user gesture. (#5666)
BUG=https://github.com/flutter/flutter/issues/5599
This commit is contained in:
parent
ed6e7fa06f
commit
6007f6af36
@ -48,13 +48,14 @@ class _CupertinoPageTransition extends AnimatedWidget {
|
||||
|
||||
_CupertinoPageTransition({
|
||||
Key key,
|
||||
Curve curve,
|
||||
Animation<double> animation,
|
||||
this.child
|
||||
}) : super(
|
||||
key: key,
|
||||
animation: _kTween.animate(new CurvedAnimation(
|
||||
parent: animation,
|
||||
curve: new _CupertinoTransitionCurve()
|
||||
curve: new _CupertinoTransitionCurve(curve)
|
||||
)
|
||||
));
|
||||
|
||||
@ -84,16 +85,33 @@ class AnimationMean extends CompoundAnimation<double> {
|
||||
double get value => (first.value + next.value) / 2.0;
|
||||
}
|
||||
|
||||
// Custom curve for iOS page transitions. The halfway point is when the page
|
||||
// is fully on-screen. 0.0 is fully off-screen to the right. 1.0 is off-screen
|
||||
// to the left.
|
||||
// Custom curve for iOS page transitions.
|
||||
class _CupertinoTransitionCurve extends Curve {
|
||||
_CupertinoTransitionCurve();
|
||||
_CupertinoTransitionCurve(this.curve);
|
||||
|
||||
Curve curve;
|
||||
|
||||
@override
|
||||
double transform(double t) {
|
||||
if (t > 0.5)
|
||||
return (t - 0.5) / 3.0 + 0.5;
|
||||
// The input [t] is the average of the current and next route's animation.
|
||||
// This means t=0.5 represents when the route is fully onscreen. At
|
||||
// t > 0.5, it is partially offscreen to the left (which happens when there
|
||||
// is another route on top). At t < 0.5, the route is to the right.
|
||||
// We divide the range into two halves, each with a different transition,
|
||||
// and scale each half to the range [0.0, 1.0] before applying curves so that
|
||||
// each half goes through the full range of the curve.
|
||||
if (t > 0.5) {
|
||||
// Route is to the left of center.
|
||||
t = (t - 0.5) * 2.0;
|
||||
if (curve != null)
|
||||
t = curve.transform(t);
|
||||
t = t / 3.0;
|
||||
t = t / 2.0 + 0.5;
|
||||
} else {
|
||||
// Route is to the right of center.
|
||||
if (curve != null)
|
||||
t = curve.transform(t * 2.0) / 2.0;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
@ -220,7 +238,8 @@ class MaterialPageRoute<T> extends PageRoute<T> {
|
||||
// TODO(mpcomplete): This hack prevents the previousRoute from animating
|
||||
// when we pop(). Remove once we fix this bug:
|
||||
// https://github.com/flutter/flutter/issues/5577
|
||||
if (!Navigator.of(context).userGestureInProgress)
|
||||
bool userGesture = Navigator.of(context).userGestureInProgress;
|
||||
if (!userGesture)
|
||||
forwardAnimation = kAlwaysDismissedAnimation;
|
||||
|
||||
ThemeData theme = Theme.of(context);
|
||||
@ -233,6 +252,10 @@ class MaterialPageRoute<T> extends PageRoute<T> {
|
||||
);
|
||||
case TargetPlatform.iOS:
|
||||
return new _CupertinoPageTransition(
|
||||
// Use a linear curve when controlled by a user gesture. This ensures
|
||||
// the animation tracks the user's finger 1:1.
|
||||
// See https://github.com/flutter/flutter/issues/5664
|
||||
curve: userGesture ? null : Curves.fastOutSlowIn,
|
||||
animation: new AnimationMean(left: animation, right: forwardAnimation),
|
||||
child: child
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user