animations 2.0.1 源码解读

animations 是一款flutter插件,提供了封装好的一些路由切换动画。最近闲来无事去看了一下它的代码,理解其关键部分代码,并实现一个精简版的animations插件。虽然不完善,但是总体思路还是对的。

首先看OpenContainer类,关键部分是传入两个Widget,一个openBuilder是打开后要展示的页面,closeBuilder被点击之后能触发动画的控件。

  Widget build(BuildContext context) {
    return OpenContainer(
      tappable: true,
      openBuilder: (context,VoidCallback _){
        return const _DetailsPage();
      },

      closedBuilder: closedBuilder,
      onClosed: onClosed,
      useRootNavigator: true,
    );
  }

OpenContainer类里面有个openContainer函数,用于切换到指定路由。

  Future<void> openContainer() async {
    await Navigator.of(context,rootNavigator:         widget.useRootNavigator).push(_OpenContainerRoute<bool>(
        closedBuilder: widget.closedBuilder,
        openBuilder: widget.openBuilder,
        hideableKey: _hideableKey,
        closedBuilderKey: _closedBuilderKey,
        useRootNavigator: widget.useRootNavigator,
        transitionDuration: Duration(milliseconds: 3000))
    );
  }

跟踪代码到类_OpenContainerRoute,看到其继承自ModolRoute类。继承此类事为了重写路由切换时的回调函数,以此来获取closeBuilder构建的控件的位置,上级路由的位置,用于指定路由切换的起点和终点。

class _OpenContainerRoute<T> extends ModalRoute<T> {
  _OpenContainerRoute({
    required this.closedBuilder,
    required this.openBuilder,
    required this.hideableKey,
    required this.closedBuilderKey,
    required this.useRootNavigator,
    required this.transitionDuration,
  });

那么重写的是哪个函数呢?关键位置如下:


  TickerFuture didPush(){
    _takeMeasurements(navigatorContext: hideableKey.currentContext!);
}

调用了_takeMeasurements测量动画的起始位置。其中hideableKey标记的是closeBuilder构造的组件的位置。

起始位置有了,控制路由切换的动画就简单了,关键代码如下:

Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
    return Align(
      alignment: Alignment.topLeft,
      child: AnimatedBuilder(
        animation: animation,
        builder: (BuildContext context, Widget? child) {
          final Animation<double> curvedAnimation = CurvedAnimation(
            parent: animation,
            curve: Curves.fastOutSlowIn,
            reverseCurve:
            false ? null : Curves.fastOutSlowIn.flipped,
          );



          final Rect rect = _rectTween.evaluate(curvedAnimation)!;
          return SizedBox.expand(
            child: Container(
              color: Colors.transparent,
              child: Align(
                  alignment: Alignment.topLeft,
                  child:  Transform.translate(
                    offset: Offset(rect.left,rect.top),
                    child: SizedBox(
                      width: rect.width,
                      height: rect.height,
                      child: Material(
                        clipBehavior: Clip.antiAlias,
                        animationDuration: Duration.zero,
                        child: Stack(
                          fit: StackFit.passthrough,
                          children: [
                            openBuilder(context, (){})
                          ],
                        ),
                      ),
                    ),
                  )
              ),
            ),
          );
        },
      ),
    );
  }

运行效果:

完整代码:GitHub - obweix/mini_animations

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值