import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../providers/subscription_provider.dart'; import '../widgets/glassmorphic_app_bar.dart'; import '../widgets/native_ad_widget.dart'; import '../widgets/analysis/analysis_screen_spacer.dart'; import '../widgets/analysis/subscription_pie_chart_card.dart'; import '../widgets/analysis/total_expense_summary_card.dart'; import '../widgets/analysis/monthly_expense_chart_card.dart'; import '../widgets/analysis/event_analysis_card.dart'; class AnalysisScreen extends StatefulWidget { const AnalysisScreen({super.key}); @override State createState() => _AnalysisScreenState(); } class _AnalysisScreenState extends State with TickerProviderStateMixin { late AnimationController _animationController; late ScrollController _scrollController; double _totalExpense = 0; List> _monthlyData = []; int _touchedIndex = -1; bool _isLoading = true; @override void initState() { super.initState(); _animationController = AnimationController( duration: const Duration(milliseconds: 1500), vsync: this, ); _scrollController = ScrollController(); _loadData(); } @override void dispose() { _animationController.dispose(); _scrollController.dispose(); super.dispose(); } Future _loadData() async { setState(() { _isLoading = true; }); final provider = Provider.of(context, listen: false); // 총 지출 계산 _totalExpense = await provider.calculateTotalExpense(); // 월별 데이터 계산 _monthlyData = await provider.getMonthlyExpenseData(); setState(() { _isLoading = false; }); // 데이터 로드 완료 후 애니메이션 시작 _animationController.forward(); } Widget _buildAnimatedAd() { return FadeTransition( opacity: CurvedAnimation( parent: _animationController, curve: const Interval(0.0, 0.5, curve: Curves.easeOut), ), child: SlideTransition( position: Tween( begin: const Offset(0, 0.2), end: Offset.zero, ).animate(CurvedAnimation( parent: _animationController, curve: const Interval(0.0, 0.5, curve: Curves.easeOut), )), child: const NativeAdWidget(key: ValueKey('analysis_ad')), ), ); } @override Widget build(BuildContext context) { return Consumer( builder: (context, provider, child) { final subscriptions = provider.subscriptions; if (_isLoading) { return const Center( child: CircularProgressIndicator(), ); } return CustomScrollView( controller: _scrollController, physics: const BouncingScrollPhysics(), slivers: [ const GlassmorphicSliverAppBar( title: '분석', pinned: true, expandedHeight: kToolbarHeight, ), // 네이티브 광고 위젯 SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.all(16), child: _buildAnimatedAd(), ), ), const AnalysisScreenSpacer(), // 1. 구독 비율 파이 차트 SubscriptionPieChartCard( subscriptions: subscriptions, animationController: _animationController, touchedIndex: _touchedIndex, onPieTouch: (index) => setState(() => _touchedIndex = index), ), const AnalysisScreenSpacer(), // 2. 총 지출 요약 카드 TotalExpenseSummaryCard( subscriptions: subscriptions, totalExpense: _totalExpense, animationController: _animationController, ), const AnalysisScreenSpacer(), // 3. 월별 지출 차트 MonthlyExpenseChartCard( monthlyData: _monthlyData, animationController: _animationController, ), const AnalysisScreenSpacer(), // 4. 이벤트 분석 EventAnalysisCard( animationController: _animationController, ), const AnalysisScreenSpacer(height: 32), ], ); }, ); } }