import 'package:flutter/material.dart'; class LoadingScreen extends StatefulWidget { final String? imagePath; final Duration animationDuration; final Color primaryColor; final Color secondaryColor; final String loadingText; final VoidCallback? onLoadingComplete; const LoadingScreen({ Key? key, this.imagePath, this.animationDuration = const Duration(seconds: 3), this.primaryColor = const Color(0xFF6366F1), this.secondaryColor = const Color(0xFFEC4899), this.loadingText = 'Loading...', this.onLoadingComplete, }) : super(key: key); @override State createState() => _LoadingScreenState(); } class _LoadingScreenState extends State with TickerProviderStateMixin { late AnimationController _progressController; late AnimationController _fadeController; late Animation _progressAnimation; late Animation _fadeAnimation; bool _isLoading = true; double _progress = 0.0; @override void initState() { super.initState(); _initializeAnimations(); _startLoading(); } void _initializeAnimations() { // Progress bar animation _progressController = AnimationController( duration: widget.animationDuration, vsync: this, ); _progressAnimation = Tween( begin: 0.0, end: 1.0, ).animate(CurvedAnimation( parent: _progressController, curve: Curves.easeInOut, )); // Fade animation for completion _fadeController = AnimationController( duration: const Duration(milliseconds: 500), vsync: this, ); _fadeAnimation = Tween( begin: 1.0, end: 0.0, ).animate(CurvedAnimation( parent: _fadeController, curve: Curves.easeOut, )); // Listen to progress changes _progressAnimation.addListener(() { setState(() { _progress = _progressAnimation.value; }); }); // Handle loading completion _progressController.addStatusListener((status) { if (status == AnimationStatus.completed) { _handleLoadingComplete(); } }); } void _startLoading() { _progressController.forward(); } void _handleLoadingComplete() { setState(() { _isLoading = false; }); // Optional fade out animation _fadeController.forward().then((_) { widget.onLoadingComplete?.call(); }); } // Public method to manually set progress void setProgress(double progress) { if (mounted) { _progressController.animateTo(progress.clamp(0.0, 1.0)); } } // Public method to complete loading void completeLoading() { if (mounted) { _progressController.forward(); } } @override void dispose() { _progressController.dispose(); _fadeController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _fadeAnimation, builder: (context, child) { return Opacity( opacity: _fadeController.isAnimating ? _fadeAnimation.value : 1.0, child: Scaffold( backgroundColor: Colors.white, body: SafeArea( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 32.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Spacer(flex: 2), // Car Icon/Image _buildCarIcon(), const SizedBox(height: 32), // Loading Text Text( widget.loadingText, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.w500, color: Color(0xFF374151), letterSpacing: 0.5, ), ), const SizedBox(height: 24), // Progress Bar _buildProgressBar(), const SizedBox(height: 16), // Progress Percentage (Optional) Text( '${(_progress * 100).toInt()}%', style: const TextStyle( fontSize: 14, color: Color(0xFF9CA3AF), fontWeight: FontWeight.w400, ), ), const Spacer(flex: 3), ], ), ), ), ), ); }, ); } Widget _buildCarIcon() { return Container( width: 80, height: 80, decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), color: Colors.grey.shade100, ), child: widget.imagePath != null ? ClipRRect( borderRadius: BorderRadius.circular(16), child: Image.asset( widget.imagePath!, width: 80, height: 80, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return _buildDefaultCarIcon(); }, ), ) : _buildDefaultCarIcon(), ); } Widget _buildDefaultCarIcon() { return Icon( Icons.directions_car_rounded, size: 40, color: widget.primaryColor, ); } Widget _buildProgressBar() { return Container( height: 8, width: double.infinity, decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), color: Colors.grey.shade200, ), child: ClipRRect( borderRadius: BorderRadius.circular(4), child: Stack( children: [ // Background Container( width: double.infinity, height: 8, color: Colors.grey.shade200, ), // Progress with gradient AnimatedBuilder( animation: _progressAnimation, builder: (context, child) { return Container( width: MediaQuery.of(context).size.width * (_progress * 0.85), // Account for padding height: 8, decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), gradient: LinearGradient( colors: [ widget.secondaryColor, widget.primaryColor, ], begin: Alignment.centerLeft, end: Alignment.centerRight, ), boxShadow: [ BoxShadow( color: widget.primaryColor.withOpacity(0.3), blurRadius: 8, offset: const Offset(0, 2), ), ], ), ); }, ), ], ), ), ); } }