0

我正在尝试在路由上实现类似 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
                  );
                },
              ),
            )
          ],
        ),
      );
    }
  );
}

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

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

4

2 回答 2

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(),
              );
            },
          );
        },
      );
    },
  ),
);

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

过渡样本

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

于 2021-04-27T09:42:37.013 回答
0

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

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

于 2021-04-27T03:35:28.903 回答