Flutter 使用自定义转场动效提升页面跳转体验

简介: 本篇带你如何完成个性化的页面切换。Flutter本身提供了不少预定义的转场动画,可以设计多种多样的转场动画实现个性化的转场效果。

fluro 转场动画源码
在使用自定义转场动画前,先扒一扒 fluro 的源码,通过源码可以发现这么一个标准的转场方法:

RouteTransitionsBuilder _standardTransitionsBuilder(
      TransitionType? transitionType) {
    return (BuildContext context, Animation<double> animation,
        Animation<double> secondaryAnimation, Widget child) {
      if (transitionType == TransitionType.fadeIn) {
        return FadeTransition(opacity: animation, child: child);
      } else {
        const Offset topLeft = const Offset(0.0, 0.0);
        const Offset topRight = const Offset(1.0, 0.0);
        const Offset bottomLeft = const Offset(0.0, 1.0);

        Offset startOffset = bottomLeft;
        Offset endOffset = topLeft;
        if (transitionType == TransitionType.inFromLeft) {
          startOffset = const Offset(-1.0, 0.0);
          endOffset = topLeft;
        } else if (transitionType == TransitionType.inFromRight) {
          startOffset = topRight;
          endOffset = topLeft;
        } else if (transitionType == TransitionType.inFromBottom) {
          startOffset = bottomLeft;
          endOffset = topLeft;
        } else if (transitionType == TransitionType.inFromTop) {
          startOffset = Offset(0.0, -1.0);
          endOffset = topLeft;
        }

        return SlideTransition(
          position: Tween<Offset>(
            begin: startOffset,
            end: endOffset,
          ).animate(animation),
          child: child,
        );
      }
    };
  }

从源码可以看出,根据不同枚举返回了不同的动画(即 transitionBuilder),其中TransitionType.fadeIn使用的是Flutter 自带的 FadeTransition,通过改变透明度来完成动画。而其他的左滑入、右滑入、下滑入和上滑入都是从初始偏移位置滑动到结束位置,使用的是 SlideTransition。Flutter 除了上述的 FadeTransitionSlideTransition 之外,还有如下的常用转场形式:

  • RotationTransition:旋转转场
  • ScaleTransition:缩放转场

既然是这样,我们可以依葫芦画瓢,先用系统其他的转场效果做一个自定义的转场看看。

旋转转场动画

先来看看旋转的转场RotationTransition,RotationTransition 的构造方法定义如下:

const RotationTransition({
    Key? key,
    required Animation<double> turns,
    this.alignment = Alignment.center,
    this.child,
  })  : assert(turns != null),
        super(key: key, listenable: turns);

其中 turns 是动画控制,表示旋转的弧度数,等于动画控制值乘以2π。alignment 表示旋转围绕的中心位置,默认是居中的。旋转的弧度不要太大,否则动画过快,导致不太好看,经过验证,推荐的起始值0.2至0.3之间,结束值为0表示回到正常位置。起始值如果为负,则是顺时针;如果为正则是逆时针,示例代码如下:

//逆时针围绕中心旋转
RouterManager.router.navigateTo(
  context,
  RouterManager.transitionPath,
  transition: TransitionType.custom,
  transitionBuilder:
      (context, animation, secondaryAnimation, child) {
    return RotationTransition(
      turns: Tween<double>(
        begin: 0.25,
        end: 0.0,
      ).animate(animation),
      child: child,
    );
  },
);

//...
//顺时针围绕左下角旋转
RouterManager.router.navigateTo(
  context,
  RouterManager.transitionPath,
  transition: TransitionType.custom,
  transitionBuilder:
      (context, animation, secondaryAnimation, child) {
    return RotationTransition(
      alignment: Alignment.bottomLeft,
      turns: Tween<double>(
        begin: -0.25,
        end: 0.0,
      ).animate(animation),
      child: child,
    );
  },
);

其中 Tween 是系统自带的线性插值方法。

缩放转场动画

缩放转场这类在图片预览会比较常见,一般是从较小的比例缩放到1:1比例。使用方式和旋转转场类似,示例代码如下:

RouterManager.router.navigateTo(
  context,
  RouterManager.transitionPath,
  transition: TransitionType.custom,
  transitionBuilder:
      (context, animation, secondaryAnimation, child) {
    return ScaleTransition(
      scale: Tween<double>(
        begin: 0.5,
        end: 1.0,
      ).animate(animation),
      child: child,
    );
  },
);

自定义转场动画

通过阅读源码,其实可以发现RotationTransitionScaleTransition 都是继承自 AnimatedWidget,因此我们可以自己写一个自定义的 Transition 继承自 AnimatedWidget,在 build方法中返回一个 Transform 对象即可。通过这种方式可以做自定义的转场动画效果。我们以变形为例,可以利用 Matrix4skew 方法,在 x 和 y 轴进行变形,就可以得到转场类似卡片变形的效果。也可以只在 X 轴或 Y 轴变形(skewXskewY 方法)。这里以 x,y 轴同时变形定义了一个转场动画:

class SkewTransition extends AnimatedWidget {
  const SkewTransition({
    Key key,
    Animation<double> turns,
    this.alignment = Alignment.center,
    this.child,
  })  : assert(turns != null),
        super(key: key, listenable: turns);

  Animation<double> get turns => listenable as Animation<double>;

  final Alignment alignment;

  final Widget child;

  @override
  Widget build(BuildContext context) {
    final double turnsValue = turns.value;
    final Matrix4 transform =
        Matrix4.skew(turnsValue * pi * 2.0, turnsValue * pi * 2.0);
    return Transform(
      transform: transform,
      alignment: alignment,
      child: child,
    );
  }
}

使用方式和 RotationTransition 类似:

RouterManager.router.navigateTo(
  context,
  RouterManager.transitionPath,
  transition: TransitionType.custom,
  transitionBuilder:
      (context, animation, secondaryAnimation, child) {
    return SkewTransition(
      turns: Tween<double>(
        begin: -0.05,
        end: 0.0,
      ).animate(animation),
      child: child,
    );
  },
);

实际也可以尝试使用围绕 X 轴旋转,围绕 Y 轴旋转,以及变更中心点位置(alignment)来实现不同的动画转场效果。如果需要更为复杂的动画效果,则可以研究动画的实现,后续篇章将有对应动画的介绍。

运行效果

运行效果如下图所示:

屏幕录制2021-06-19 下午2.07.33.gif

总结

本篇介绍了 fluro 导航到其他页面的自定义转场动画实现,Flutter本身提供了不少预定义的转场动画,可以通过 transitionBuilder 参数设计多种多样的转场动画,也可以通过自定义的 AnimatedWidget实现个性化的转场动画效果。


欢迎关注个人公众号:岛上码农

相关文章
|
定位技术 开发工具 开发者
为了让外卖小哥在地图里开上火箭🚀我用FLutter自定义了地图
花了五天时间,用Flutter自定义地图是什么体验?外卖小哥都开上火箭了?什么?我被女朋友赶出家门啦?欢迎观看被女友赶出家门之开火箭送外卖篇~
|
23小时前
|
数据库 Android开发
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
|
3天前
|
前端开发 搜索推荐 开发者
【Flutter前端技术开发专栏】Flutter中的自定义主题与暗黑模式
【4月更文挑战第30天】本文介绍了如何在Flutter中自定义主题和实现暗黑模式。通过`ThemeData`类定义应用的外观,包括颜色、字体和样式。示例展示了如何设置主色、强调色及文本、按钮主题。暗黑模式可通过`darkTheme`属性启用,结合`ThemeData.dark()`方法定制。利用`MediaQuery`监听系统亮度变化,动态调整暗黑模式状态。Flutter的这些特性有助于开发者创建独特且用户友好的界面。
【Flutter前端技术开发专栏】Flutter中的自定义主题与暗黑模式
|
3天前
|
缓存 前端开发 搜索推荐
【Flutter前端技术开发专栏】Flutter中的自定义绘制与Canvas API
【4月更文挑战第30天】Flutter允许开发者通过`CustomPaint`和`CustomPainter`进行自定义绘制,以实现丰富视觉效果。`CustomPaint` widget将`CustomPainter`应用到画布,而`CustomPainter`需实现`paint`和`shouldRepaint`方法。`paint`用于绘制图形,如示例中创建的`MyCirclePainter`绘制蓝色圆圈。Canvas API提供绘制形状、路径、文本和图片等功能。注意性能优化,避免不必要的重绘和利用缓存提升效率。自定义绘制让Flutter UI更具灵活性和个性化,但也需要图形学知识和性能意识。
【Flutter前端技术开发专栏】Flutter中的自定义绘制与Canvas API
|
3天前
|
开发框架 前端开发 搜索推荐
【Flutter前端技术开发专栏】Flutter中的自定义Widget与渲染流程
【4月更文挑战第30天】探索Flutter的自定义Widget与渲染流程。自定义Widget是实现复杂UI设计的关键,优点在于个性化设计、功能扩展和代码复用,但也面临性能优化和复杂性管理的挑战。创建步骤包括设计结构、定义Widget类、实现构建逻辑和处理交互。Flutter渲染流程涉及渲染对象树、布局、绘制和合成阶段。实践案例展示如何创建带渐变背景和阴影的自定义按钮。了解这些知识能提升应用体验并应对开发挑战。查阅官方文档以深入学习。
【Flutter前端技术开发专栏】Flutter中的自定义Widget与渲染流程
|
3天前
|
前端开发 开发者 iOS开发
【Flutter前端技术开发专栏】Flutter中的路由管理与页面跳转
【4月更文挑战第30天】本文介绍了Flutter的路由管理与页面跳转,包括基本和命名路由管理。基本路由使用`Navigator`的`push`和`pop`方法,如`MaterialPageRoute`和`CupertinoPageRoute`。命名路由则通过路由表注册名称进行跳转,如`Navigator.pushNamed`。此外,还展示了如何通过构造函数、`arguments`和`PageRouteBuilder`进行路由传值。掌握这些知识能提升Flutter开发效率。
【Flutter前端技术开发专栏】Flutter中的路由管理与页面跳转
|
3天前
|
前端开发 开发者 UED
Flutter的自定义Painter:深入探索自定义绘制Widget的技术实现
【4月更文挑战第26天】Flutter的自定义Painter允许开发者根据需求绘制独特UI,通过继承`CustomPaint`类和重写`paint`方法实现。在`paint`中使用`Canvas`绘制图形、路径等。创建自定义Painter类后,将其作为`CustomPaint` Widget的`painter`属性使用。此技术可实现自定义形状、渐变、动画等复杂效果,提升应用视觉体验。随着Flutter的进化,自定义Painter将提供更丰富的功能。
|
3天前
|
运维 监控 定位技术
应用研发平台EMAS常见问题之flutter插件不支持自定义图标如何解决
应用研发平台EMAS(Enterprise Mobile Application Service)是阿里云提供的一个全栈移动应用开发平台,集成了应用开发、测试、部署、监控和运营服务;本合集旨在总结EMAS产品在应用开发和运维过程中的常见问题及解决方案,助力开发者和企业高效解决技术难题,加速移动应用的上线和稳定运行。
81 0
|
3天前
Flutter 自定义ICON库
Flutter 自定义ICON库 Flutter提供了一些内置的ICON库,但在实际开发中,可能需要一些自定义的ICON图标。Flutter允许我们使用自定义图标,本文将介绍如何创建和使用自定义ICON库。
|
3天前
|
UED
Flutter之自定义路由切换动画
Flutter之自定义路由切换动画 在Flutter中,我们可以通过Navigator来实现路由管理,包括路由的跳转和返回等。默认情况下,Flutter提供了一些简单的路由切换动画,但是有时候我们需要自定义一些特殊的动画效果来提高用户体验。本文将介绍如何在Flutter中实现自定义的路由切换动画。