3 回复
抱歉,我还没到那个level。作为屌丝程序猿,还在努力学习基础呢~
更多关于Flutter进阶动画技巧教程的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
建议多动手实践,掌握AnimationController、Tween等核心类的使用,学会配合Builder和Listener优化动画效果。
Flutter 提供了强大的动画支持,以下是一些进阶动画技巧,帮助你创建更复杂和流畅的用户体验。
1. 使用 AnimatedBuilder
和 AnimationController
AnimatedBuilder
是一个非常有用的 widget,它允许你在动画过程中重建部分 UI,而不需要重建整个 widget 树。结合 AnimationController
,你可以精确控制动画的播放。
class MyAnimatedWidget extends StatefulWidget {
@override
_MyAnimatedWidgetState createState() => _MyAnimatedWidgetState();
}
class _MyAnimatedWidgetState extends State<MyAnimatedWidget> with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..repeat(reverse: true);
_animation = Tween<double>(begin: 0, end: 1).animate(_controller);
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Opacity(
opacity: _animation.value,
child: child,
);
},
child: FlutterLogo(size: 100),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
2. 使用 Hero
动画
Hero
动画用于在不同页面之间共享元素,创建平滑的过渡效果。只需在两个页面的相同元素上使用相同的 tag
。
// Page 1
Hero(
tag: 'hero-tag',
child: FlutterLogo(size: 100),
);
// Page 2
Hero(
tag: 'hero-tag',
child: FlutterLogo(size: 200),
);
3. 使用 CustomPainter
和 Canvas
绘制自定义动画
CustomPainter
允许你使用 Canvas
绘制自定义图形和动画。你可以通过重写 paint
方法来实现复杂的动画效果。
class MyCustomPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.blue
..style = PaintingStyle.fill;
canvas.drawCircle(Offset(size.width / 2, size.height / 2), 50, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
class MyAnimatedPainter extends StatefulWidget {
@override
_MyAnimatedPainterState createState() => _MyAnimatedPainterState();
}
class _MyAnimatedPainterState extends State<MyAnimatedPainter> with SingleTickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..repeat();
}
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: MyCustomPainter(),
size: Size(200, 200),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
4. 使用 TweenSequence
和 CurvedAnimation
TweenSequence
允许你定义一系列 Tween
,并在动画过程中依次应用它们。CurvedAnimation
则允许你使用曲线来控制动画的速度。
Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..repeat();
_animation = TweenSequence<double>(
<TweenSequenceItem<double>>[
TweenSequenceItem<double>(
tween: Tween<double>(begin: 0, end: 1),
weight: 50,
),
TweenSequenceItem<double>(
tween: Tween<double>(begin: 1, end: 0),
weight: 50,
),
],
).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
));
}
5. 使用 AnimatedList
和 SliverAnimatedList
AnimatedList
和 SliverAnimatedList
允许你在列表中添加或删除项时应用动画效果。
final GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>();
List<String> _items = [];
void _addItem() {
_items.insert(0, 'Item ${_items.length + 1}');
_listKey.currentState.insertItem(0);
}
void _removeItem(int index) {
final item = _items.removeAt(index);
_listKey.currentState.removeItem(index, (context, animation) {
return SizeTransition(
sizeFactor: animation,
child: ListTile(title: Text(item)),
);
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
ElevatedButton(
onPressed: _addItem,
child: Text('Add Item'),
),
Expanded(
child: AnimatedList(
key: _listKey,
initialItemCount: _items.length,
itemBuilder: (context, index, animation) {
return SizeTransition(
sizeFactor: animation,
child: ListTile(
title: Text(_items[index]),
onTap: () => _removeItem(index),
),
);
},
),
),
],
);
}
这些技巧可以帮助你在 Flutter 中创建更复杂和吸引人的动画效果。