Flutter 在项目中使用动画(不使用包)
前言
动画对于 web 和移动应用程序都非常重要。但是在移动应用程序中不应该使用夸张的动画。简单但是很多动画使你的应用程序更好用。以至于当你点击一个按钮时,一种平滑的感觉或者页面过渡都会影响到你。
正文
1 按下按钮柔软的感觉
class _CustomButtonState extends State<CustomButton>
with SingleTickerProviderStateMixin {
late double _scale;
late AnimationController _controller;
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 350),
lowerBound: 0.0,
upperBound: 0.1,
)..addListener(() {
setState(() {});
});
}
void dispose() {
_controller.dispose();
super.dispose();
}
void _tapDown(TapDownDetails details) {
_controller.forward();
}
void _tapUp(TapUpDetails details) {
_controller.reverse();
}
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));
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,
);
void dispose() {
_controller.dispose();
super.dispose();
}
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;
State<ChangingText> createState() => _ChangingTextState();
}
class _ChangingTextState extends State<ChangingText>
with TickerProviderStateMixin {
late AnimationController _controller;
late TextStyleTween _styleTween;
late CurvedAnimation _curvedAnimation;
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,
);
}
void dispose() {
_controller.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Center(
child: DefaultTextStyleTransition(
style: _styleTween.animate(_curvedAnimation),
child: CustomText(widget.text),
),
);
}
}
我在这里使用了 repeat() 。这意味着它将连续运行。您可以在要显示给用户的文本、按钮、卡片 widget 中显示这一点。也许是竞选宣言。我把你留给你的想象力,所有你要做的就是复制动画相关的代码,并发挥他们:)
代码
https://github.com/bedirhanssaglam/flutter-animations
结束语
如果本文对你有帮助,请转发让更多的朋友阅读。
也许这个操作只要你 3 秒钟,对我来说是一个激励,感谢。
祝你有一个美好的一天~
© 猫哥
微信 ducafecat
https://wiki.ducafecat.tech
https://ducafecat.com