Files
TravelMate/lib/components/loading/laoding_content.dart

162 lines
4.8 KiB
Dart

import 'package:flutter/material.dart';
class LoadingContent extends StatefulWidget {
final Future<void> Function()? onBackgroundTask;
final String? loadingText;
final VoidCallback? onComplete;
const LoadingContent({
super.key,
this.onBackgroundTask,
this.loadingText = "Chargement en cours...",
this.onComplete,
});
@override
State<LoadingContent> createState() => _LoadingContentState();
}
class _LoadingContentState extends State<LoadingContent>
with TickerProviderStateMixin {
late AnimationController _rotationController;
late AnimationController _pulseController;
late Animation<double> _rotationAnimation;
late Animation<double> _pulseAnimation;
@override
void initState() {
super.initState();
_rotationController = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..repeat();
_pulseController = AnimationController(
duration: const Duration(milliseconds: 1500),
vsync: this,
)..repeat(reverse: true);
_rotationAnimation = Tween<double>(
begin: 0,
end: 1,
).animate(_rotationController);
_pulseAnimation = Tween<double>(begin: 0.8, end: 1.2).animate(
CurvedAnimation(parent: _pulseController, curve: Curves.easeInOut),
);
_executeBackgroundTask();
}
Future<void> _executeBackgroundTask() async {
if (widget.onBackgroundTask != null) {
try {
await widget.onBackgroundTask!();
if (widget.onComplete != null) {
widget.onComplete!();
}
} catch (e) {
debugPrint('Erreur lors de la tâche en arrière-plan: $e');
}
}
}
@override
void dispose() {
_rotationController.dispose();
_pulseController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final isDark = theme.brightness == Brightness.dark;
return Scaffold(
backgroundColor: theme.scaffoldBackgroundColor,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Animation de rotation et pulsation
AnimatedBuilder(
animation: Listenable.merge([
_rotationAnimation,
_pulseAnimation,
]),
builder: (context, child) {
return Transform.scale(
scale: _pulseAnimation.value,
child: RotationTransition(
turns: _rotationAnimation,
child: Container(
width: 80,
height: 80,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
colors: [
theme.primaryColor.withValues(alpha: 0.8),
theme.primaryColor,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
boxShadow: [
BoxShadow(
color: theme.primaryColor.withValues(alpha: 0.3),
blurRadius: 20,
spreadRadius: 5,
),
],
),
child: Icon(
Icons.travel_explore,
color: Colors.white,
size: 40,
),
),
),
);
},
),
const SizedBox(height: 40),
// Texte de chargement avec animation
AnimatedBuilder(
animation: _pulseController,
builder: (context, child) {
return Opacity(
opacity: _pulseAnimation.value - 0.3,
child: Text(
widget.loadingText ?? "Chargement en cours...",
style: theme.textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.w500,
color: isDark ? Colors.white : Colors.black,
),
textAlign: TextAlign.center,
),
);
},
),
const SizedBox(height: 20),
// Indicateur de progression linéaire
SizedBox(
width: 200,
child: LinearProgressIndicator(
backgroundColor: isDark
? Colors.grey[800]
: Colors.grey.shade300,
valueColor: AlwaysStoppedAnimation<Color>(theme.primaryColor),
),
),
],
),
),
);
}
}