Flutter 앱: 달력 팝업 UI 개선
- 달력 열기 애니메이션 추가 (아래로 부드럽게 펼쳐짐) - 툴바 영역 오버레이 제외 (툴바 아래부터 반투명 배경) - 년월 텍스트 가운데 고정, 화살표는 옆에 별도 위치 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
21bd887f5e
commit
895d9c26a3
1 changed files with 74 additions and 43 deletions
|
|
@ -118,10 +118,14 @@ class _ScheduleViewState extends ConsumerState<ScheduleView> {
|
|||
),
|
||||
],
|
||||
),
|
||||
// 달력 팝업 오버레이
|
||||
// 달력 팝업 오버레이 (툴바 아래부터)
|
||||
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<ScheduleView> {
|
|||
),
|
||||
),
|
||||
),
|
||||
// 달력 팝업
|
||||
// 달력 팝업 (애니메이션)
|
||||
Positioned(
|
||||
top: MediaQuery.of(context).padding.top + 56,
|
||||
left: 0,
|
||||
|
|
@ -196,7 +200,11 @@ class _ScheduleViewState extends ConsumerState<ScheduleView> {
|
|||
),
|
||||
// 년월 표시
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
// 년월 텍스트 (가운데 고정)
|
||||
GestureDetector(
|
||||
onTap: _showCalendar
|
||||
? () {
|
||||
setState(() {
|
||||
|
|
@ -205,11 +213,7 @@ class _ScheduleViewState extends ConsumerState<ScheduleView> {
|
|||
});
|
||||
}
|
||||
: null,
|
||||
child: Center(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
child: Text(
|
||||
'${displayDate.year}년 ${displayDate.month}월',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
|
|
@ -219,9 +223,20 @@ class _ScheduleViewState extends ConsumerState<ScheduleView> {
|
|||
: 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<ScheduleView> {
|
|||
? AppColors.primary
|
||||
: AppColors.textPrimary,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// 다음 월
|
||||
|
|
@ -271,7 +285,23 @@ class _ScheduleViewState extends ConsumerState<ScheduleView> {
|
|||
|
||||
/// 달력 팝업 빌드
|
||||
Widget _buildCalendarPopup(ScheduleState state, ScheduleController controller) {
|
||||
return Material(
|
||||
return TweenAnimationBuilder<double>(
|
||||
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(
|
||||
|
|
@ -282,6 +312,7 @@ class _ScheduleViewState extends ConsumerState<ScheduleView> {
|
|||
firstChild: _buildCalendarGrid(state, controller),
|
||||
secondChild: _buildYearMonthPicker(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue