|
@@ -0,0 +1,139 @@
|
|
|
+import 'dart:math';
|
|
|
+
|
|
|
+import 'package:fis_ui/index.dart';
|
|
|
+import 'package:flutter/material.dart';
|
|
|
+import 'package:fis_theme/theme.dart';
|
|
|
+
|
|
|
+class OuterPainter extends CustomPainter {
|
|
|
+ @override
|
|
|
+ void paint(Canvas canvas, Size size) {
|
|
|
+ ///canvas 是我们作画的画布,Size则是父widget给我们的画布大小
|
|
|
+ ///也可以通过CustomPaint的size属性指定,
|
|
|
+ ///其次如果CustomPaint的child不为空,这个size的值会与child大小有关
|
|
|
+ ///CustomPaint的size将被忽略
|
|
|
+ ///初始化一个画笔
|
|
|
+ Paint paint = Paint();
|
|
|
+ paint.color = FTheme.ins.colorScheme.primary;
|
|
|
+ paint.strokeWidth = 6;
|
|
|
+
|
|
|
+ ///画笔粗细
|
|
|
+ paint.isAntiAlias = true;
|
|
|
+
|
|
|
+ ///抗锯齿
|
|
|
+ paint.style = PaintingStyle.stroke;
|
|
|
+
|
|
|
+ ///默认是fill,我们不需要填充,选stroke
|
|
|
+ ///首先我们需要一个矩形,画布好根据这个矩形来确定圆的位置(这个圆是抽象的)
|
|
|
+ Rect rect = Rect.fromCircle(
|
|
|
+ center: Offset(size.width / 2, size.height / 2),
|
|
|
+ radius: size.width / 2,
|
|
|
+ );
|
|
|
+
|
|
|
+ /// drawArc 绘制一条弧线
|
|
|
+ /// 参数1 确定圆的矩形,
|
|
|
+ /// 参数2和3,分别是起始位置和扫过的角度,它原名是叫startAngle 和 sweepAngle,
|
|
|
+ /// 0.0从中心点到右侧0度 , 扫过pi/2 度 (90度),
|
|
|
+ /// 参数4(userCenter)false 只绘制一个弧线、如果是true,则会绘制一个扇形
|
|
|
+ /// 参数5 画笔
|
|
|
+ canvas.drawArc(rect, 0.0, pi / 2, false, paint);
|
|
|
+
|
|
|
+ ///因为是中心对称,所以我们将位置移动180度
|
|
|
+ canvas.drawArc(rect, pi, pi / 2, false, paint);
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ bool shouldRepaint(CustomPainter oldDelegate) {
|
|
|
+ return false;
|
|
|
+
|
|
|
+ ///如果你的painter和一个动画绑定,理论上这里应是true(或者根据自己需要的值进行判断)表示需要重绘
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class LoaddingOrErrorPage extends StatefulWidget implements FWidget {
|
|
|
+ const LoaddingOrErrorPage();
|
|
|
+ @override
|
|
|
+ State<StatefulWidget> createState() {
|
|
|
+ return LoaddingOrErrorPageState();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class LoaddingOrErrorPageState extends State<LoaddingOrErrorPage>
|
|
|
+ with TickerProviderStateMixin {
|
|
|
+ late AnimationController outerController, innerController;
|
|
|
+ late Animation<double> outerAnim, innerAnim;
|
|
|
+
|
|
|
+ @override
|
|
|
+ void dispose() {
|
|
|
+ outerController.dispose();
|
|
|
+ innerController.dispose();
|
|
|
+ super.dispose();
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ void initState() {
|
|
|
+ super.initState();
|
|
|
+ outerController = AnimationController(
|
|
|
+ vsync: this, duration: const Duration(milliseconds: 3000));
|
|
|
+ innerController = AnimationController(
|
|
|
+ vsync: this, duration: const Duration(milliseconds: 2000));
|
|
|
+
|
|
|
+ outerAnim = Tween(begin: 0.0, end: 2.0).animate(outerController);
|
|
|
+ innerAnim = Tween(begin: 1.0, end: 0.0).animate(innerController);
|
|
|
+ innerController.addStatusListener((status) {
|
|
|
+ if (status == AnimationStatus.completed) {
|
|
|
+ innerController.reset();
|
|
|
+ innerController.forward();
|
|
|
+ } else if (status == AnimationStatus.dismissed) {
|
|
|
+ innerController.forward();
|
|
|
+ } else if (status == AnimationStatus.forward) {
|
|
|
+ } else if (status == AnimationStatus.reverse) {}
|
|
|
+ });
|
|
|
+ outerController.addStatusListener((status) {
|
|
|
+ if (status == AnimationStatus.completed) {
|
|
|
+ outerController.reset();
|
|
|
+ outerController.forward();
|
|
|
+ } else if (status == AnimationStatus.dismissed) {
|
|
|
+ outerController.forward();
|
|
|
+ } else if (status == AnimationStatus.forward) {
|
|
|
+ } else if (status == AnimationStatus.reverse) {}
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ Widget build(BuildContext context) {
|
|
|
+ if (!outerController.isAnimating) outerController.forward();
|
|
|
+ if (!innerController.isAnimating) innerController.forward();
|
|
|
+ return Container(
|
|
|
+ child: Column(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.center,
|
|
|
+ children: <Widget>[
|
|
|
+ Stack(
|
|
|
+ alignment: Alignment.center,
|
|
|
+ children: <Widget>[
|
|
|
+ RotationTransition(
|
|
|
+ turns: outerAnim,
|
|
|
+ child: SizedBox(
|
|
|
+ width: 150,
|
|
|
+ height: 150,
|
|
|
+ child: CustomPaint(
|
|
|
+ painter: OuterPainter(),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ RotationTransition(
|
|
|
+ turns: innerAnim,
|
|
|
+ child: SizedBox(
|
|
|
+ width: 136,
|
|
|
+ height: 136,
|
|
|
+ child: CustomPaint(
|
|
|
+ painter: OuterPainter(),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|