Flutter动画关键帧插件keyframe的使用
Flutter动画关键帧插件keyframe的使用
通过将Tweens转换为带有关键帧的Timeline,可以改善Flutter中的动画体验,就像视频编辑器一样,但使用编程语言来实现。
示例代码
example/lib/main.dart
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:keyframe/keyframe.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// 这个小部件是你的应用的根。
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
late final AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
_controller.addListener(() {
setState(() {});
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
final bool _initialized = false;
init() {
if (_initialized) return;
registerExtension('ext.keyframe.up', (method, parameters) async {
return ServiceExtensionResponse.result(
jsonEncode({
'index': 1,
'value': 2,
}),
);
});
}
@override
Widget build(BuildContext context) {
final timeline = Timeline(
properties: [
KeyframeProperty<Color>(
[
Keyframe<Color>(0, Colors.red),
Keyframe<Color>(0.5, Colors.green),
Keyframe<Color>(0.7, Colors.blue),
Keyframe<Color>(1, Colors.red),
],
),
KeyframeProperty<Size>(
[
Keyframe(0, const Size(200, 200)),
Keyframe(0.5, const Size(300, 200)),
Keyframe(0.7, const Size(300, 300)),
Keyframe(1.0, const Size(200, 200)),
],
),
],
).animate(_controller);
final color = timeline.value<Color>();
final size = timeline.value<Size>();
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: size.width,
height: size.height,
color: color,
),
const Text(
'你已经点击了按钮很多次:',
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_controller.reset();
_controller.forward();
init();
print(extensionStreamHasListener);
postEvent('ext.keyframe', {
'test': 'dsfdfd',
});
},
tooltip: '增加',
child: const Icon(Icons.add),
),
);
}
}
代码解释
-
导入必要的库
import 'dart:convert'; import 'dart:log'; import 'package:flutter/material.dart'; import 'package:keyframe/keyframe.dart'; -
创建主应用类
class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } -
创建主页状态管理类
class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } -
初始化控制器
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin { late final AnimationController _controller; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(seconds: 2), vsync: this, ); _controller.addListener(() { setState(() {}); }); } -
定义关键帧属性
final timeline = Timeline( properties: [ KeyframeProperty<Color>( [ Keyframe<Color>(0, Colors.red), Keyframe<Color>(0.5, Colors.green), Keyframe<Color>(0.7, Colors.blue), Keyframe<Color>(1, Colors.red), ], ), KeyframeProperty<Size>( [ Keyframe(0, const Size(200, 200)), Keyframe(0.5, const Size(300, 200)), Keyframe(0.7, const Size(300, 300)), Keyframe(1.0, const Size(200, 200)), ], ), ], ).animate(_controller); -
设置UI组件
return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: size.width, height: size.height, color: color, ), const Text( '你已经点击了按钮很多次:', ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: () { _controller.reset(); _controller.forward(); init(); print(extensionStreamHasListener); postEvent('ext.keyframe', { 'test': 'dsfdfd', }); }, tooltip: '增加', child: const Icon(Icons.add), ), );
更多关于Flutter动画关键帧插件keyframe的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复
更多关于Flutter动画关键帧插件keyframe的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在 Flutter 中,keyframe 是一个用于创建复杂动画的插件,它允许你定义一系列关键帧(Keyframe),并在这些关键帧之间进行平滑的过渡。keyframe 插件可以帮助你更灵活地控制动画的细节,尤其是在需要实现复杂动画效果时。
安装 keyframe 插件
首先,你需要在 pubspec.yaml 文件中添加 keyframe 插件的依赖:
dependencies:
flutter:
sdk: flutter
keyframe: ^1.0.0
然后运行 flutter pub get 来安装依赖。
使用 keyframe 插件
1. 导入 keyframe 插件
import 'package:keyframe/keyframe.dart';
2. 创建关键帧动画
你可以通过定义一系列关键帧来创建动画。每个关键帧都包含一个时间点和对应的属性值。
class MyAnimatedWidget extends StatefulWidget {
@override
_MyAnimatedWidgetState createState() => _MyAnimatedWidgetState();
}
class _MyAnimatedWidgetState extends State<MyAnimatedWidget>
with SingleTickerProviderStateMixin {
AnimationController _controller;
KeyframeAnimation<Color> _colorAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(seconds: 2),
);
_colorAnimation = KeyframeAnimation(
controller: _controller,
keyframes: [
Keyframe(Color(0xFF0000FF), 0.0), // 蓝色, 开始时间 0.0
Keyframe(Color(0xFF00FF00), 0.5), // 绿色, 开始时间 0.5
Keyframe(Color(0xFFFF0000), 1.0), // 红色, 开始时间 1.0
],
);
_controller.repeat(reverse: true); // 循环播放动画
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Container(
width: 100,
height: 100,
color: _colorAnimation.value,
);
},
);
}
}
3. 解释代码
- AnimationController: 用于控制动画的播放、暂停、停止等操作。
- KeyframeAnimation: 创建一个关键帧动画,传入
AnimationController和一系列关键帧。 - Keyframe: 定义关键帧,包含一个值和一个时间点。时间点是相对于动画总时长的比例(0.0 到 1.0)。
- AnimatedBuilder: 用于在动画值变化时重建 UI。
4. 运行效果
上面的代码会创建一个矩形,颜色会从蓝色变为绿色,再变为红色,然后反向循环播放。
其他用途
keyframe 插件不仅可以用颜色动画,还可以用于其他类型的动画,如位置、大小、透明度等。你只需要定义相应的关键帧和动画类型即可。
KeyframeAnimation<Offset> _positionAnimation = KeyframeAnimation(
controller: _controller,
keyframes: [
Keyframe(Offset(0, 0), 0.0),
Keyframe(Offset(100, 100), 0.5),
Keyframe(Offset(200, 0), 1.0),
],
);

