关于 lightweight-flutter-animations
一种 Flutter 动画实现方法,通过使用 ticker 的 AnimationWidget 替代 State 基类。指南展示了用 CustomPainter 绘制,以及无需调用 setState 即可重建界面。
主要功能
- 01基于 ticker 的动画组件
- 02跟踪经过时间与时间差
- 03访问布局约束
- 04CustomPainter 画布示例
适用场景
- 01构建 ticker 驱动的动画
- 02在画布上绘制动画内容
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ rodydavis/ skills --skill lightweight-flutter-animations安装后在 Claude Code 中输入/lightweight-flutter-animations确认已加载。
详细介绍
轻量级 Flutter 动画
概述
首先,我们需要创建抽象类:
abstract class AnimationWidget<T extends StatefulWidget> extends State<T>
with SingleTickerProviderStateMixin {
Duration elapsed = Duration.zero;
Duration delta = Duration.zero;
late final Ticker ticker;
BoxConstraints constraints = const BoxConstraints.tightFor();
@override
void initState() {
super.initState();
ticker = createTicker((elapsed) {
delta = elapsed - this.elapsed;
this.elapsed = elapsed;
update(elapsed);
if (mounted) setState(() {});
});
ticker.start();
WidgetsBinding.instance.addPostFrameCallback(start);
}
@override
void dispose() {
ticker.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, dimens) {
constraints = dimens;
return paint(context, dimens);
});
}
void start(Duration time) {}
void update(Duration time);
Widget paint(BuildContext context, BoxConstraints constraints);
}
这样我们就可以用 AnimationWidget 替换 State,无需调用 setState 即可重建 UI。
示例
此示例需要一个内联画布绘制器:
class InlinePainter extends CustomPainter {
InlinePainter({
required this.draw,
super.repaint,
});
final void Function(Canvas canvas, Size size) draw;
@override
void paint(Canvas canvas, Size size) {
draw(canvas, size);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
以下是使用新组件类的示例:
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
class SimpleExample extends StatefulWidget {
const SimpleExample({Key? key}) : super(key: key);
@override
State<SimpleExample> createState() => _SimpleExampleState();
}
class _SimpleExampleState extends AnimationWidget<SimpleExample> {
var x = 0.0;
var y = 0.0;
var z = 0.0;
@override
void update(Duration time) {
final t = delta.inMilliseconds / 1000;
x += t;
y += t;
z += t;
}
@override
Widget paint(BuildContext context, BoxConstraints constraints) {
return Material(
child: Center(
child: Container(
width: 100,
height: 100,
transform: Matrix4.identity()
..rotateX(x)
..rotateY(y)
..rotateZ(z),
child: const Text(
'Hello World',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
),
),
);
}
}
演示
评论
支持 Markdown