LighthouseApp/lib/app/widgets/kr_simple_loading.dart
speakeloudest 75d4c48e41
Some checks failed
Build Windows / build (push) Has been cancelled
feat: 源码提交
2025-10-19 23:30:54 -07:00

232 lines
5.5 KiB
Dart
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
/// 简单的加载动画组件替代有问题的flutter_spinkit
class KRSimpleLoading extends StatefulWidget {
final Color? color;
final double size;
final Duration duration;
const KRSimpleLoading({
super.key,
this.color,
this.size = 40.0,
this.duration = const Duration(milliseconds: 1000),
});
@override
State<KRSimpleLoading> createState() => _KRSimpleLoadingState();
}
class _KRSimpleLoadingState extends State<KRSimpleLoading>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: widget.duration,
vsync: this,
);
_animation = Tween<double>(
begin: 0.0,
end: 1.0,
).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
));
_controller.repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Transform.rotate(
angle: _animation.value * 2 * 3.14159,
child: Container(
width: widget.size,
height: widget.size,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: widget.color ?? Theme.of(context).primaryColor,
width: 2.0,
),
),
child: Padding(
padding: const EdgeInsets.all(2.0),
child: CircularProgressIndicator(
strokeWidth: 2.0,
valueColor: AlwaysStoppedAnimation<Color>(
widget.color ?? Theme.of(context).primaryColor,
),
),
),
),
);
},
);
}
}
/// 脉冲加载动画
class KRSimplePulse extends StatefulWidget {
final Color? color;
final double size;
final Duration duration;
const KRSimplePulse({
super.key,
this.color,
this.size = 40.0,
this.duration = const Duration(milliseconds: 1500),
});
@override
State<KRSimplePulse> createState() => _KRSimplePulseState();
}
class _KRSimplePulseState extends State<KRSimplePulse>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: widget.duration,
vsync: this,
);
_animation = Tween<double>(
begin: 0.0,
end: 1.0,
).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
));
_controller.repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Transform.scale(
scale: 0.5 + (_animation.value * 0.5),
child: Opacity(
opacity: 1.0 - _animation.value,
child: Container(
width: widget.size,
height: widget.size,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: widget.color ?? Theme.of(context).primaryColor,
),
),
),
);
},
);
}
}
/// 波浪加载动画
class KRSimpleWave extends StatefulWidget {
final Color? color;
final double size;
final Duration duration;
const KRSimpleWave({
super.key,
this.color,
this.size = 40.0,
this.duration = const Duration(milliseconds: 1200),
});
@override
State<KRSimpleWave> createState() => _KRSimpleWaveState();
}
class _KRSimpleWaveState extends State<KRSimpleWave>
with TickerProviderStateMixin {
late List<AnimationController> _controllers;
late List<Animation<double>> _animations;
@override
void initState() {
super.initState();
_controllers = List.generate(3, (index) {
return AnimationController(
duration: widget.duration,
vsync: this,
);
});
_animations = _controllers.map((controller) {
return Tween<double>(
begin: 0.0,
end: 1.0,
).animate(CurvedAnimation(
parent: controller,
curve: Curves.easeInOut,
));
}).toList();
for (int i = 0; i < _controllers.length; i++) {
Future.delayed(Duration(milliseconds: i * 200), () {
if (mounted) {
_controllers[i].repeat();
}
});
}
}
@override
void dispose() {
for (var controller in _controllers) {
controller.dispose();
}
super.dispose();
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(3, (index) {
return AnimatedBuilder(
animation: _animations[index],
builder: (context, child) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 2.0),
width: widget.size / 6,
height: widget.size * (0.3 + (_animations[index].value * 0.7)),
decoration: BoxDecoration(
color: widget.color ?? Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(2.0),
),
);
},
);
}),
);
}
}