Flutter动画效果插件cn_animations的使用
Flutter动画效果插件cn_animations的使用
Flutter 是由一系列小部件(widgets)组成的,对添加简单的淡入或滑动动画应该不难。实际上,这应该像在当前小部件之上添加一个新小部件一样简单。这就是此插件试图帮助你实现的目标。
功能
基本动画:
- 淡入
- 滑动
- 缩放
路由感知动画
结合淡入和滑动动画与导航事件。
- 同页推/弹动画
- 下一页推/弹动画
需要设置。(见下文)
路由感知小部件
根据导航事件运行函数。(推、弹、推下一页、弹下一页)
它在 CnRouteAwareAnimation
中使用。
需要设置。(见下文)
开始使用
如果你只想使用基本动画,那就可以直接开始!
如果你想使用 RouteAwareWidget
或 CnRouteAwareAnimation
,则需要设置 routeObserver
。
设置:在 MaterialApp
中添加 routeObserver
(主程序)
MaterialApp(
navigatorObservers: [routeObserver],
)
使用方法
基本动画
只需将这些小部件添加到目标小部件上方即可。
CnFade(
child: child,
)
CnSlide(
begin: const Offset(-0.2, 0),
duration: const Duration(milliseconds: 500),
// 动画开始前的延迟时间
delay: const Duration(milliseconds: 100),
curve: Curves.easeIn,
child: child,
)
如果你愿意,可以将动画控制器传递给小部件。 但持续时间不会被覆盖。
CnScale(
begin: 0.5,
controller: _controller,
child: child,
)
路由感知动画
如果只是将其添加到你的小部件顶部,它将在所有导航事件上执行基本的淡入和滑动动画。
CnRouteAwareAnimation(
child: child,
)
你可以通过更改输入值来区分同页和下一页动画。
以下值设置后,子小部件将从页面左侧进入并在右侧离开。
CnRouteAwareAnimation(
// 同页动画开始位置
beginSamePage: const Offset(-0.5, 0),
// 下一页动画结束位置
endNextPage: const Offset(0.5, 0),
// 禁用所有导航事件的淡入动画
showFadeAnimation: false,
child: child,
)
示例代码
以下是完整的示例代码,展示如何使用 cn_animations
插件。
import 'package:cn_animations/cn_animations.dart';
import 'package:cn_animations/route_aware_widget.dart';
import 'package:example/restart_widget.dart';
import 'package:flutter/material.dart';
void main() {
runApp(
RestartWidget(
child: MaterialApp(
home: const MyHomePage(),
theme: ThemeData(primarySwatch: Colors.teal),
navigatorObservers: [routeObserver],
),
),
);
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Cn Animations Example"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CnFade(
duration: const Duration(milliseconds: 1000),
child: _buildChild(0, "Fade"),
),
CnScale(
duration: const Duration(milliseconds: 500),
child: _buildChild(1, "Scale"),
),
CnSlide(
begin: const Offset(-0.1, 0),
duration: const Duration(milliseconds: 500),
child: _buildChild(2, "Slide"),
),
// 可以链式组合动画
// 将第一个动画的持续时间作为第二个动画的延迟时间,依此类推
// 确保取消之前的值
// 这可能非常低效
CnSlide(
begin: const Offset(-0.3, 0),
end: const Offset(0.03, 0),
duration: const Duration(milliseconds: 300),
child: CnSlide(
begin: const Offset(0.03, 0),
// 取消另一个动画的结束值
end: const Offset(-0.03, 0),
delay: const Duration(milliseconds: 300),
duration: const Duration(milliseconds: 200),
child: _buildChild(3, "Chained"),
),
),
// 可以轻松组合不同的动画
// 如果经常使用某种组合,
// 提取为一个组件并仅添加该组件
CnFade(
duration: const Duration(milliseconds: 700),
child: CnSlide(
begin: const Offset(0, 0.2),
delayInMilliseconds: 100,
child: CnScale(
duration: const Duration(milliseconds: 500),
begin: 0.7,
child: _buildChild(4, "Combined"),
),
),
),
],
),
),
// 保存更改后重新播放动画
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.replay_rounded),
onPressed: () => RestartWidget.restartApp(context),
),
);
}
Widget _buildChild(int index, String title) {
// 点击主页上的任何项目导航到下一页
void navigate() {
Navigator.push(
context,
// 使用 CnRouteAwareAnimation 的最佳方式
// 在导航时使用 FadeTransition
PageRouteBuilder(
pageBuilder: (_, __, ___) => const NewPage(),
transitionDuration: const Duration(milliseconds: 500),
transitionsBuilder: (_, a, __, c) =>
FadeTransition(opacity: a, child: c),
),
);
}
return CnRouteAwareAnimation(
showPush: false, // 禁用初始推动画
// 使用索引,不同项移动到不同的终点
// 使用相同的动画持续时间
// 因此它们移动得更快
endNextPage: Offset(0.15 + index * 0.1, 0),
child: _buildButton(title, onTap: navigate),
);
}
}
// 显示第一页项目的效果 [CnRouteAwareAnimation]
class NewPage extends StatelessWidget {
const NewPage({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("New Page")),
body: Center(
child: CnRouteAwareAnimation(
beginSamePage: const Offset(0, -0.5),
child: _buildButton(
"Back",
height: 50,
width: 200,
onTap: () => Navigator.pop(context),
),
),
),
);
}
}
Widget _buildButton(String text,
{double height = 100, double width = 100, required Function onTap}) {
return GestureDetector(
onTap: () => onTap(),
child: Container(
height: height,
width: width,
margin: const EdgeInsets.only(bottom: 10),
decoration: BoxDecoration(
color: Colors.teal,
borderRadius: BorderRadius.circular(10),
),
child: Center(
child: Text(
text,
style: const TextStyle(color: Colors.white),
),
),
),
);
}
更多关于Flutter动画效果插件cn_animations的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复