New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在FLBFlutterViewContainer内调用Navigator.push方法,第一个页面push到第二个页面动画有问题。 #466
Comments
这个效果实际上由 CupertinoPageTransition 的三个组合动画构成 CupertinoPageTransition({
Key key,
@required Animation<double> primaryRouteAnimation,
@required Animation<double> secondaryRouteAnimation,
@required this.child,
@required bool linearTransition,
}) : assert(linearTransition != null),
_primaryPositionAnimation =
(linearTransition
? primaryRouteAnimation
: CurvedAnimation(
parent: primaryRouteAnimation,
curve: Curves.linearToEaseOut,
reverseCurve: Curves.easeInToLinear,
)
).drive(_kRightMiddleTween),
_secondaryPositionAnimation =
(linearTransition
? secondaryRouteAnimation
: CurvedAnimation(
parent: secondaryRouteAnimation,
curve: Curves.linearToEaseOut,
reverseCurve: Curves.easeInToLinear,
)
).drive(_kMiddleLeftTween),
_primaryShadowAnimation =
(linearTransition
? primaryRouteAnimation
: CurvedAnimation(
parent: primaryRouteAnimation,
curve: Curves.linearToEaseOut,
)
).drive(_kGradientShadowTween),
super(key: key); 第一页进行 page transition 的时候 _secondaryPositionAnimation 的值并未正确发生改变,怀疑是动画的控制器未启动动画,还需验证。 之前推测 FlutterBoost 自定义的 BoostPageRoute 中根据平台使用了 CupertinoPageRoute,查验后发现并没有使用。昨天根据链路记录了一些可能与这个 issue 相关的类与方法,我先写在下面: 在 TransitionRoute 中创建的 _secondaryAnimation final ProxyAnimation _secondaryAnimation = ProxyAnimation(kAlwaysDismissedAnimation);
AnimationController createAnimationController() {
assert(!_transitionCompleter.isCompleted, 'Cannot reuse a $runtimeType after disposing it.');
final Duration duration = transitionDuration;
assert(duration != null && duration >= Duration.zero);
return AnimationController(
duration: duration,
debugLabel: debugLabel,
vsync: navigator,
);
} 调用中的 PageRoute 有判断是否为初始 Route abstract class PageRoute<T> extends ModalRoute<T> {
AnimationController createAnimationController() {
final AnimationController controller = super.createAnimationController();
if (settings.isInitialRoute)
controller.value = 1.0;
return controller;
} 由于第一个页面初始化的时候我们并不需要路由转换动画,所以 controller.value 就直接设为 1.0,是否有可能判断这个在 push 之前,这样就还是认为当前的 route 为initial route,从而误设置 controller。 供参考。 |
经验证 settings.isInitialRoute 中的判断没有问题 |
经验证 AnimationController 的行为也是正常的 |
定位到问题: abstract class TransitionRoute<T> extends OverlayRoute<T> {
void _updateSecondaryAnimation(Route<dynamic> nextRoute) {
if (nextRoute is TransitionRoute<dynamic> && canTransitionTo(nextRoute) && nextRoute.canTransitionFrom(this)) {
此处的判断应该为 true ,第一次动画时判断为 false,导致后续 final Animation<double> current = _secondaryAnimation.parent;
_secondaryAnimation.parent = TrainHoppingAnimation(current, nextRoute._animation); 未执行,动画未成功初始化。 |
void _updateSecondaryAnimation(Route nextRoute) 在第一个页面 push 第二个页面的时候,此方法被调用了两次, 第一次: flutter: nextRoute is TransitionRoute:false transition (PageTransitionsTheme::buildTransitions)没有执行 第二次: flutter: nextRoute is TransitionRoute:true nextRoute.canTransitionFrom(this) 为 false |
若去掉 nextRoute.canTransitionFrom(this) 这个问题可以被解决,但还不清楚会造成什么样的影响 |
默认 但是这个可以背重写,调用该方法的 route 为传入的 route,推测为 CupertinoPageRoute |
CupertinoPageRoute 的 canTransitionFrom 判断应该有问题: @override
bool canTransitionFrom(TransitionRoute<dynamic> previousRoute) {
return previousRoute is CupertinoPageRoute;
} 这里判断的前一个 Route 是否为 CupertinoPageRoute,若前一个 Route 并不是 CupertinoPageRoute,而当前 push 的 Route 为 CupertinoPageRoute 那么这个方法依然会返回 false。 |
MaterialPageRoute 不会出现这个问题,参考 MaterialPageRoute 更改 CupertinoPageRoute 中 canTransitionFrom @override
bool canTransitionFrom(TransitionRoute<dynamic> previousRoute) {
return previousRoute is MaterialPageRoute || previousRoute is CupertinoPageRoute;
} 验证可以修复 CupertinoPageRoute 中的第一页 push page 页面动画不一致的问题。 |
哇,非常感谢你的帮助。经过验证你说的方法确实是可行的。 |
FlutterBoost 问题点好像有些不同,即使使用 MaterialPageRoute 也会出现这个现象,这个还要继续跟踪下;) |
刚测试了下,FlutterBoost 的也被解决了 |
你是用的什么跳转方式,我这边用MaterialPageRoute还是存在这个问题。 |
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>FirstRouteWidget())); 就是普通 MaterialPageRoute,Cupertino 那个你改了之后检查下是否 import material package,否则会编译失败。 |
FlutterBoost 中 BoostPageRoute 的 buildTransitions 重写有问题 @override
Widget buildTransitions(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
return child;
} 这里只 return child 将会丢失动画的信息,应该返回父类的结果,改成以下内容: @override
Widget buildTransitions(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
return super.buildTransitions(context, animation, secondaryAnimation, child);
} 经验证,可以解决 FlutterBoost 页面跳转动画问题 |
see also: flutter/flutter#44864 |
该 issue 已在最新 flutter master 版本中被 fix 掉!感谢你的反馈! |
最终解决方案与该 issue 讨论有所不同,我们选择了去掉 |
A push B正常动画是A页面有一个向左移动的动画,但是从gif看pageone -> pagetwo没有这个动画。
The text was updated successfully, but these errors were encountered: