这一节主要了解一下Flutter中的回弹动画,实现这一过程主要分如下几步: `
- 创建一个动画控制器
- 使用手势移动 widget
- 对 widget 进行动画
- 计算速度以模拟弹跳运动 `
栗子如下:
import 'package:flutter/material.dart';
import 'package:flutter/physics.dart';
void main() {
runApp(const MaterialApp(home: DragAnimationDemo(),));
}
```
class DragAnimationDemo extends StatelessWidget {
const DragAnimationDemo({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: const DraggableCard(child: FlutterLogo(size: 128,)),
);
}
}
class DraggableCard extends StatefulWidget {
const DraggableCard({required this.child, super.key});
final Widget child;
@override
State<DraggableCard> createState() => _DraggableCardState();
}
class _DraggableCardState extends State<DraggableCard>
with SingleTickerProviderStateMixin{
late AnimationController _controller;
Alignment _dragAlignment = Alignment.center;
late Animation<Alignment> _animation;
@override
void initState() {
// TODO: implement initState
super.initState();
_controller = AnimationController(vsync: this);
_controller.addListener(() {
setState(() {
_dragAlignment = _animation.value;
});
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void _runAnimation(Offset pixelsPerSecond,Size size) {
_animation = _controller.drive(
AlignmentTween(begin: _dragAlignment,end: Alignment.center)
);
final unitsPerSecondX = pixelsPerSecond.dx/size.width;
final unitsPerSecondY = pixelsPerSecond.dy/size.height;
final unitsPerSecond = Offset(unitsPerSecondX, unitsPerSecondY);
final unitVelocity = unitsPerSecond.distance;
const spring = SpringDescription(mass: 30
, stiffness: 1, damping: 1);
final simulation = SpringSimulation(spring, 0, 1, -unitVelocity);
_controller.animateWith(simulation);
}
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return GestureDetector(
onPanDown: (details) {
_controller.stop();
},
onPanUpdate: (details) {
setState(() {
_dragAlignment += Alignment(
details.delta.dx/(size.width/2),
details.delta.dy / (size.height/2)
);
});
},
onPanEnd: (details) {
_runAnimation(details.velocity.pixelsPerSecond,size);
},
child: Align(
alignment: _dragAlignment,
child: Card(
child: widget.child,
),
),
);
}
}