效果
考察内容
AnimationController Tween AnimatedBuilder Transform Matrix4
实现
///源码:https://github.com/yixiaolunhui/flutter_xy
class LoadingView extends StatefulWidget {const LoadingView({Key? key}) : super(key: key);@overrideState<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;@overridevoid 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();}@overridevoid dispose() {_controller.dispose();super.dispose();}@overrideWidget 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);@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("动画"),),body: const Center(child: LoadingView()),);}
}