我们在Flutter上实现CircularRevealAnimation,并同时在pub.dev上发布库

Android具有View动画的一个非常有趣的功能,称为CircularRevealAnimation字面意思是“圆形公开”。 反过来,尽管Flutter具有丰富的动画小部件功能,但它并没有提供此类动画。



本文将展示如何使用Flutter实现这种动画,并在pub.dev上发布该库,以方便访问和分发。


动画实现


在Flutter中,一切都是小部件。 动画也不例外。 因此,我们创建了CircularRevealAnimation类,它将扩展StatelessWidget类。


使用AnimationController完成开始,停止和其他动画控制。 要创建AnimationController您需要从StatefulWidget继承,并向State添加一个特殊的类SingleTickerProviderStateMixin


我们的动画类CircularRevealAnimation将不会自行管理动画,但是将接收Animation<double>作为必需的构造函数参数,因此无需继承StatefulWidget 。 这样做是为了可以将CircularRevealAnimation与使用相同AnimationController其他动画轻松组合。 例如,将公开动画与透明度更改动画相结合。


CircularRevealAnimation构造函数的另一个重要参数是child ,它是动画的子控件,它将显示或消失。 通常,在Flutter中,许多小部件都有一个child参数。 此类小部件允许您更改子小部件的行为,渲染或布局。 或添加动画,如CircularRevealAnimation


另外,要指定动画,将需要诸如动画的开口(或闭合)的中心以及开口的最小和最大半径之类的参数。 这些参数是可选的,可以在创建动画时指定为null或完全不指定。 在这种情况下,将使用默认值:披露中心将位于窗口小部件的中心,最小半径将被缠绕为零,最大半径将等于从披露中心到窗口小部件的顶点的距离,该顶点距离披露中心最远。


默认的最大半径计算算法如下。 首先,计算从中心到距公开中心最远的顶点的水平和垂直距离,然后通过勾股定理计算对角线。


 static double calcMaxRadius(Size size, Offset center) { final w = max(center.dx, size.width - center.dx); final h = max(center.dy, size.height - center.dy); return sqrt(w * w + h * h); } 

现在,您需要在渲染期间在圆内实现小部件的裁剪。 ClipPath类将帮助我们解决这个问题,它使您可以根据任意模板裁剪小部件。 作为参数,此小部件将传递给clipper (稍后再介绍),并且child是需要裁剪的子小部件。


ClipPath小部件的clipper参数确定如何裁剪子小部件。 若要创建您自己的裁剪模板,请创建CircularRevealClipper类,该类继承CustomClipper<Path>类,然后重新定义Path getClip(Size size)方法。 此方法返回限制裁剪区域的Path 。 在我们的情况下,该区域是一个具有给定中心的圆。 要计算圆的半径,您需要知道动画的当前值。 此值作为fraction参数传递到CircularRevealClipper 。 使用最小半径和最大半径之间的线性插值来计算圆的半径。


之后,让我们继续小部件的实现。 使用AnimatedBuilder创建动画很方便。 AnimatedBuilder构造函数接受Animation<double>对象和用于根据当前动画值构建窗口小部件的builder 。 在builder我们创建一个ClipPath并将动画的当前值( fraction )传递给CircularRevealClipper


 class CircularRevealAnimation extends StatelessWidget { ... @override Widget build(BuildContext context) { return AnimatedBuilder( animation: animation, builder: (BuildContext context, Widget _) { return ClipPath( clipper: CircularRevealClipper( fraction: animation.value, center: center, minRadius: minRadius, maxRadius: maxRadius, ), child: this.child, ); }, ); } } 

这样就完成了CircularRevealAnimation的创建。 仍然可以使用它。 为此,创建一个StatefulWidgetAnimationController并将AnimationController传递给CircularRevealAnimation


使用范例
 import 'package:flutter/material.dart'; import 'package:circular_reveal_animation/circular_reveal_animation.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'CRA Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin { AnimationController animationController; Animation<double> animation; @override void initState() { super.initState(); animationController = AnimationController( vsync: this, duration: Duration(milliseconds: 1000), ); animation = CurvedAnimation( parent: animationController, curve: Curves.easeIn, ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("CRA Demo"), ), body: Padding( padding: const EdgeInsets.all(16.0), child: CircularRevealAnimation( minRadius: 12, maxRadius: 200, center: Offset(0, 300), child: Container(color: Colors.red), animation: animation, ), ), floatingActionButton: FloatingActionButton(onPressed: () { if (animationController.status == AnimationStatus.forward || animationController.status == AnimationStatus.completed) { animationController.reverse(); } else { animationController.forward(); } }), ); } } 

Github演示应用程序


图书馆创作


要创建Dart或Flutter库,您需要将pubspec.yaml文件添加到与Dart文件的lib目录相同的目录中。 该文件包含库的描述,有关作者和依赖项的信息。


创建定义公共API的文件也是一种好习惯。 该文件位于lib文件夹中,包括库的名称和公共API中需要包含的文件列表。 所有其他Dart文件都放在src目录中。 这不仅隐藏了公共API中未包含的文件,而且还允许您使用单个import表达式来导入库。 该文件的内容:


 library circular_reveal_animation; export 'package:circular_reveal_animation/src/circular_reveal_animation.dart'; 

您可以在此处阅读有关在Dart上创建库的更多信息。


发布到pub.dev


将Dart库发布到pub.dev非常简单。 您需要做的就是从库的根目录运行flutter packages pub publish命令。 发布是代表Google帐户进行的,因此在发布过程中会提供一个链接,该链接必须在浏览器中打开并登录到Google。 随后,只能使用代表发布第一版的帐户发布更新。


发布之前,建议您使用flutter packages pub publish --dry-run验证库是否正确。


运行flutter packages pub publish库将立即在pub.dev上可用。 而且,正如文档所述,“永远发布”-以后您只能上传新版本。 较旧的版本也将可用。


尽管图书馆出版看起来很简单,但它也有陷阱。 例如,在发布第一个版本时,由于该库的描述(在pubspec.yaml )太短,因此我在评分中pubspec.yaml


您可以在此处阅读有关发布库的更多信息。


实际上,是pub.devgithub.com上的circular_reveal_animation库。


PS:我用```java {...} ```突出显示了Dart代码。 最好在habr.com上添加Dart代码突出显示。

Source: https://habr.com/ru/post/zh-CN452072/


All Articles