diff --git a/app/lib/views/schedule/schedule_view.dart b/app/lib/views/schedule/schedule_view.dart index 5fa3c64..c3576bf 100644 --- a/app/lib/views/schedule/schedule_view.dart +++ b/app/lib/views/schedule/schedule_view.dart @@ -118,10 +118,14 @@ class _ScheduleViewState extends ConsumerState { ), ], ), - // 달력 팝업 오버레이 + // 달력 팝업 오버레이 (툴바 아래부터) if (_showCalendar) ...[ - // 배경 오버레이 - Positioned.fill( + // 배경 오버레이 (툴바 제외) + Positioned( + top: MediaQuery.of(context).padding.top + 56, + left: 0, + right: 0, + bottom: 0, child: GestureDetector( onTap: () { setState(() { @@ -134,7 +138,7 @@ class _ScheduleViewState extends ConsumerState { ), ), ), - // 달력 팝업 + // 달력 팝업 (애니메이션) Positioned( top: MediaQuery.of(context).padding.top + 56, left: 0, @@ -196,32 +200,43 @@ class _ScheduleViewState extends ConsumerState { ), // 년월 표시 Expanded( - child: GestureDetector( - onTap: _showCalendar - ? () { - setState(() { - _showYearMonthPicker = !_showYearMonthPicker; - _yearRangeStart = (_calendarViewDate.year ~/ 12) * 12; - }); - } - : null, - child: Center( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - '${displayDate.year}년 ${displayDate.month}월', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: _showYearMonthPicker - ? AppColors.primary - : AppColors.textPrimary, - ), + child: Stack( + alignment: Alignment.center, + children: [ + // 년월 텍스트 (가운데 고정) + GestureDetector( + onTap: _showCalendar + ? () { + setState(() { + _showYearMonthPicker = !_showYearMonthPicker; + _yearRangeStart = (_calendarViewDate.year ~/ 12) * 12; + }); + } + : null, + child: Text( + '${displayDate.year}년 ${displayDate.month}월', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: _showYearMonthPicker + ? AppColors.primary + : AppColors.textPrimary, ), - if (_showCalendar) ...[ - const SizedBox(width: 4), - Icon( + ), + ), + // 화살표 (년월 옆에 위치) + if (_showCalendar) + Positioned( + // 년월 텍스트 너비의 절반 + 여백 + left: MediaQuery.of(context).size.width / 2 - 48 + 52, + child: GestureDetector( + onTap: () { + setState(() { + _showYearMonthPicker = !_showYearMonthPicker; + _yearRangeStart = (_calendarViewDate.year ~/ 12) * 12; + }); + }, + child: Icon( _showYearMonthPicker ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down, @@ -230,10 +245,9 @@ class _ScheduleViewState extends ConsumerState { ? AppColors.primary : AppColors.textPrimary, ), - ], - ], - ), - ), + ), + ), + ], ), ), // 다음 월 @@ -271,16 +285,33 @@ class _ScheduleViewState extends ConsumerState { /// 달력 팝업 빌드 Widget _buildCalendarPopup(ScheduleState state, ScheduleController controller) { - return Material( - color: Colors.white, - elevation: 8, - child: AnimatedCrossFade( - duration: const Duration(milliseconds: 150), - crossFadeState: _showYearMonthPicker - ? CrossFadeState.showSecond - : CrossFadeState.showFirst, - firstChild: _buildCalendarGrid(state, controller), - secondChild: _buildYearMonthPicker(), + return TweenAnimationBuilder( + duration: const Duration(milliseconds: 200), + curve: Curves.easeOut, + tween: Tween(begin: 0.0, end: 1.0), + builder: (context, value, child) { + return ClipRect( + child: Align( + alignment: Alignment.topCenter, + heightFactor: value, + child: Opacity( + opacity: value, + child: child, + ), + ), + ); + }, + child: Material( + color: Colors.white, + elevation: 8, + child: AnimatedCrossFade( + duration: const Duration(milliseconds: 150), + crossFadeState: _showYearMonthPicker + ? CrossFadeState.showSecond + : CrossFadeState.showFirst, + firstChild: _buildCalendarGrid(state, controller), + secondChild: _buildYearMonthPicker(), + ), ), ); }