如何在颤动中相对于前一个路由转换动画

Posted

技术标签:

【中文标题】如何在颤动中相对于前一个路由转换动画【英文标题】:How to animate routes transtion relative to the previous one in flutter 【发布时间】:2021-07-13 18:39:23 【问题描述】:

我正在尝试在路由上实现类似 coupertino 页面转换的功能。 (简要介绍如何定位先前和当前路线并为其设置动画)。

我检查了这个包page_transition,但使用的逻辑似乎不正确,因为它重建了先前的上下文小部件并试图破解新路线中的动画。

即使在文档中,它似乎也只是关于导航堆栈顶部的路线。

你最终会得到这样的结果:

 Navigator.of(context).push(AnimatedRoute(
                      prevPage: widget, nextPage: Page2()));
class AnimatedRoute extends PageRouteBuilder 

  final Widget nextPage;
  final Widget prevPage;

  AnimatedRoute(this.prevPage, this.nextPage) : super(
    transitionDuration: Duration(milliseconds: 700),
    pageBuilder: (
      BuildContext context,
      Animation<double> animation,
      Animation<double> secondaryAnimation,
    ) 
      return nextPage;
    ,
    maintainState: true,
    transitionsBuilder: (
      BuildContext context,
      Animation<double> animation,
      Animation<double> secondaryAnimation,
      Widget child,
    ) 
      return Material(
        child: Stack(
          overflow: Overflow.visible,
          children: <Widget>[
            SlideTransition(
              position: Tween<Offset>(
                begin: const Offset(0.0, 0.0),
                end: const Offset(-0.3, 0.0),
              ).animate(animation),
              child: prevPage,
            ),

            SlideTransition(
              position: Tween<Offset>(
                begin: const Offset(1.0, 0.0),
                end: Offset.zero,
              ).animate(animation),
              child: AnimatedBuilder(
                animation: animation,
                builder: (c, w) 
                  return Material(
                    shadowColor: Colors.black,
                    // elevation: 10.0 * animation.value,
                    child: nextPage
                  );
                ,
              ),
            )
          ],
        ),
      );
    
  );

除了重建之外,这也没有考虑旧小部件的状态。

一种更好的处理方式,值得赞赏

【问题讨论】:

【参考方案1】:

您可以使用PageRouteBuilder 来处理您要转换的页面和您要转换到的页面的转换,如下所述:

注意:pageBuilder 有 3 个参数: 上下文、动画和辅助动画。 animation 在页面被导航到时使用,secondaryAnimation 在页面从导航时使用。

假设我们有两个页面,A 和 B。

对于页面 A:

Navigator.of(context).push(
  PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) 
      return AnimatedBuilder(
        animation: animation,
        builder: (context, child) 
          return AnimatedBuilder(
            animation: secondaryAnimation,
            builder: (context, innerChild) 
              retrun Transform.scale(
                scale: (animation.value - secondaryAnimation.value),
                child: A(),
              );
            ,
          );
        ,
      );
    ,
  ),
);

对于页面 B:

Navigator.of(context).push(
  PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) 
      return AnimatedBuilder(
        animation: animation,
        builder: (context, child) 
          return AnimatedBuilder(
            animation: secondaryAnimation,
            builder: (context, child) 
              return Transform.translate(
                offset: Offset(
                  1.0 - animation.value,
                  0.0,
                ),
                child: B(),
              );
            ,
          );
        ,
      );
    ,
  ),
);

这将导致如下图所示的过渡:

Transition sample

(gif说明:第一页缩小,第二页像幻灯片过渡一样进来)

【讨论】:

您能否分享一个代码的工作示例 也使用 3 个虚拟页面,我在推送命名路由时看到了一些故障 @bihireboris 这里是你如何使用命名路由来处理它:***.com/questions/56792479/… 我实际上找到了one working example here...我仍然认为secondaryAnimation 应该在您正在推动的***路线上处理...在上一条路线上更难制作动态 @bihireboris 虽然这是关于 Flutter API 的,但我认为我们无能为力。无论如何,如果我的回答对您有用,我会很高兴为您点赞。【参考方案2】:

还有其他的包也可以像你一样使用 getx,虽然它的功能很臃肿,但它仍然有很多过渡来应用黑白两个页面。如果你愿意,你也可以查看他们的源代码。

另外你为什么不使用 Cupertino Transition,它很棒并且受到 Flutter 的支持?

【讨论】:

我需要了解他们如何为自定义动画的两条路线设置动画,而且 coupertino 路由不提供大量自定义

以上是关于如何在颤动中相对于前一个路由转换动画的主要内容,如果未能解决你的问题,请参考以下文章

如何在颤动中制作水平滚动动画

如何在颤动中使用动画列表对最初渲染的项目进行动画处理

如何在颤动中缩小和放大图标动画?

如何在颤动中添加主题切换动画?

如何在颤动的屏幕开始处添加动画显示

如何在颤动中为折叠元素设置动画