Flutter在项目中使用动画不使用包实现详解
作者:会煮咖啡的猫
前言
动画对于 web 和移动应用程序都非常重要。但是在移动应用程序中不应该使用夸张的动画。简单但是很多动画使你的应用程序更好用。以至于当你点击一个按钮时,一种平滑的感觉或者页面过渡都会影响到你。
正文
1 按下按钮柔软的感觉
class _CustomButtonState extends State<CustomButton> with SingleTickerProviderStateMixin { late double _scale; late AnimationController _controller; @override void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 350), lowerBound: 0.0, upperBound: 0.1, )..addListener(() { setState(() {}); }); } @override void dispose() { _controller.dispose(); super.dispose(); } void _tapDown(TapDownDetails details) { _controller.forward(); } void _tapUp(TapUpDetails details) { _controller.reverse(); } @override Widget build(BuildContext context) { _scale = 1 - _controller.value; return GestureDetector( onTap: widget.onTap, onTapDown: _tapDown, onTapUp: _tapUp, child: Transform.scale( scale: _scale, child:
首先,我们创建一个名为 CustomButton 的 StatewWidget。我们将在应用程序的任何地方使用这个按钮。也许宽度,里面的文字会改变。在最后一个子部分之后,我们将设计我们的按钮。(我不想在这里占用太多的空间,你可以在文章的最后找到完成项目的源代码)。
在我们看到模拟器中的动画之前,我们还有一个场景。当我们按下这个按钮时,我们希望出现一个弹出窗口。弹出窗口突然出现在 Flutter 的屏幕上。同样,我们可以通过使用动画给人一种柔软的感觉。请确保您的应用程序将更加专业和吸引眼球的方式:)
return showGeneralDialog( context: context, pageBuilder: (context, animation, secondaryAnimation) { return ScaleTransition( scale: Tween<double>(begin: 0.5, end: 1).animate(animation), child: AlertDialog(
只要将这些 widget 包装在 AlertDialog 的顶部,您就会看到一个非常漂亮的效果
2 想要一个像 Instagram 一样的喜欢按钮吗?
class _FavoritesButtonState extends State<FavoritesButton> with SingleTickerProviderStateMixin { bool isFavorite = false; late final AnimationController _controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 300)); @override Widget build(BuildContext context) { return Container( height: 10.h, width: 10.w, decoration: const BoxDecoration( shape: BoxShape.circle, color: Colors.white, boxShadow: [ BoxShadow( offset: Offset(0, 1), color: Colors.grey, blurRadius: 1, ), ], ), child: AnimatedBuilder( animation: _controller, builder: (context, child) => GestureDetector( child: isFavorite ? AnimatedSwitcher( switchInCurve: Curves.easeInOutBack, transitionBuilder: (child, animation) => ScaleTransition( scale: animation, child: child, ), duration: const Duration(milliseconds: 300), child: Icon( Icons.favorite, size: 3.7.h, color: Colors.red, key: const ValueKey('isFav'), )) : AnimatedSwitcher( switchInCurve: Curves.easeInOutBack, transitionBuilder: (child, animation) => ScaleTransition( scale: animation, child: child, ), duration: const Duration(milliseconds: 300), child: Icon( Icons.favorite_border_outlined, size: 3.7.h, color: Colors.grey, key: const ValueKey('isNotFav'), ), ), onTap: () { setState(() { isFavorite = !isFavorite; }); }, )), ); } }
当 isFavorite 状态改变时,动画将出现,按钮的内部将被涂成红色。这里最重要的部分是关键作业。如果您不这样做,系统将检测到两个相同的动画将不会出现。
3 动画页面过渡
实际上,这里有一个包依赖项。不过别担心,这是必要的。因为在 Flutter Navigator.push() 等方法现在是原始的。我强烈推荐使用 GoRoute 或 AutoRoute。在本文中,我们将讨论 GoRoute 中可用的动画。
import 'package:animations/view/empty/empty_view.dart'; import 'package:animations/view/home/home_view.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; animationPage({required GoRouterState state, required Widget route}) => CustomTransitionPage<void>( key: state.pageKey, child: route, transitionsBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) => SlideTransition( position: animation.drive( Tween<Offset>( begin: const Offset(-1, 0), end: Offset.zero, ).chain(CurveTween(curve: Curves.fastOutSlowIn)), ), child: child, ), ); final routes = GoRouter( initialLocation: '/home', debugLogDiagnostics: true, routes: [ GoRoute( path: '/home', pageBuilder: (context, state) { return animationPage( state: state, route: const HomeView(), ); }, routes: [ GoRoute( path: 'empty', pageBuilder: (context, state) { return animationPage( state: state, route: const EmptyView(), ); }, ), ], ), ], );
下面是将执行主要工作的方法 animationPage() 。我们用这种方法包装相关页面并完成工作。您可以通过更改 start: const Offset (-1,0)值来实现不同的动画。我想像书页一样过渡。这就是它看起来的样子
此外,我想提出一个批评。如果不使用动画,页面转换在 Flutter 中是非常粗糙的。
4 动画文字
通过您现在将看到的动画,您可以在页面首次打开时显示可滚动的文本。闲话少说,让我们检查一下代码,然后讨论一下我们能做些什么。
class _AnimatedTextState extends State<AnimatedText> with TickerProviderStateMixin { late final AnimationController _controller = AnimationController( duration: const Duration(seconds: 3), vsync: this, )..forward(); late final Animation<double> _animation = CurvedAnimation( parent: _controller, curve: Curves.fastOutSlowIn, ); @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return SizeTransition( sizeFactor: _animation, axis: Axis.horizontal, axisAlignment: -1, child: CustomText( widget.text, textStyle: widget.textStyle, ), ); } }
我想让你注意两件事。第一个是。.正向()方法正向()方法。这表示当打开该页面时,该动画仅显示一次。如果用 repeat() 替换它,它将是连续的。第二,轴对齐参数。我做了这个 -1。文本从左到右。如果我做 1,它会是相反的。这是我最喜欢的动画。您可以将此动画应用于除 Text 之外的许多其他 widget 。
5 更改/闪动文本样式
class ChangingText extends StatefulWidget { const ChangingText(this.text, {super.key}); final String text; @override State<ChangingText> createState() => _ChangingTextState(); } class _ChangingTextState extends State<ChangingText> with TickerProviderStateMixin { late AnimationController _controller; late TextStyleTween _styleTween; late CurvedAnimation _curvedAnimation; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(milliseconds: 750), vsync: this, )..repeat(reverse: true); _styleTween = TextStyleTween( begin: GoogleFonts.poppins( fontSize: 15.sp, color: AppConstants.java, ), end: TextStyle( fontSize: 15.sp, color: AppConstants.bittersweet, ), ); _curvedAnimation = CurvedAnimation( parent: _controller, curve: Curves.elasticInOut, ); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Center( child: DefaultTextStyleTransition( style: _styleTween.animate(_curvedAnimation), child: CustomText(widget.text), ), ); } }
我在这里使用了 repeat() 。这意味着它将连续运行。您可以在要显示给用户的文本、按钮、卡片 widget 中显示这一点。也许是竞选宣言。我把你留给你的想象力,所有你要做的就是复制动画相关的代码,并发挥他们:)
代码
以上就是Flutter在项目中使用动画不使用包实现详解的详细内容,更多关于Flutter项目动画使用的资料请关注脚本之家其它相关文章!