效果
考察内容
- AnimationController
- Tween
- AnimatedBuilder
- Transform
- Matrix4
实现
///源码:https://github.com/yixiaolunhui/flutter_xy class LoadingView extends StatefulWidget { const LoadingView({Key? key}) : super(key: key); @override State<LoadingView> createState() => _LoadingViewState(); } class _LoadingViewState extends State<LoadingView> with TickerProviderStateMixin { late AnimationController _controller; late Animation<double> _rotationAnimation; late Animation<double> _radiusAnimation; var size = 160.0; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(seconds: 2), vsync: this, ); _rotationAnimation = Tween<double>(begin: 0.0, end: pi) .chain(CurveTween(curve: Curves.easeInOut)) .animate(_controller); _radiusAnimation = Tween(begin: size / 2, end: 5.0) .chain(CurveTween(curve: Curves.easeInOut)) .animate(_controller); _controller.addStatusListener((status) { if (status == AnimationStatus.completed) { _rotationAnimation = Tween<double>( begin: _rotationAnimation.value % (2 * pi), end: _rotationAnimation.value % (2 * pi) + pi, ).chain(CurveTween(curve: Curves.easeInOut)).animate(_controller); _radiusAnimation = Tween<double>( begin: _radiusAnimation.value == size / 2 ? size / 2 : 5.0, end: _radiusAnimation.value == size / 2 ? 5.0 : size / 2, ).chain(CurveTween(curve: Curves.easeInOut)).animate(_controller); _controller ..reset() ..forward(); } }); _controller.forward(); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _controller, builder: (BuildContext context, Widget? child) { return Stack( clipBehavior: Clip.none, alignment: Alignment.center, children: [ for (var i = 0; i < 5; i++) Transform( alignment: Alignment.center, transform: Matrix4.identity() ..rotateZ(_rotationAnimation.value + i * 0.2), child: Container( width: size - i * 30, height: size - i * 30, decoration: BoxDecoration( color: Colors.deepPurple[400 - i * 100], borderRadius: BorderRadius.circular(_radiusAnimation.value), ), ), ), ], ); }, ); } }
使用
///源码:https://github.com/yixiaolunhui/flutter_xy class LoadingPage extends StatelessWidget { const LoadingPage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("动画"), ), body: const Center(child: LoadingView()), ); } }