mark340
착하게살자
mark340
전체 방문자
오늘
어제
  • 분류 전체보기 (98)
    • 백준 (11)
    • 알고리즘 (1)
    • Javascript (17)
    • CS (18)
    • 기타 (9)
    • AI (1)
    • Angular (2)
    • Linux (14)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • parsing
  • oauth
  • JavaScript
  • Closure
  • MySQL

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
mark340

착하게살자

카테고리 없음

Flutter DateSelector & showDatePicker: 효과적인 날짜 선택 구현하기

2024. 8. 22. 10:35

Flutter 앱에서 사용되는 showDatePicker 의 효과적인 사용방법에 대해 이야기해보려고 합니다.
아래 위젯은 사용자가 일간, 주간, 월간 데이터를 쉽게 탐색할 수 있게 해주는 중요한 UI 요소입니다.

DateSelector 위젯 소개

DateSelector는 다음과 같은 주요 기능을 제공합니다:

  1. 현재 선택된 날짜 표시
  2. 날짜 증가/감소 버튼
  3. 달력을 통한 날짜 선택
  4. 일간/주간/월간 모드 지원

이제 각 부분을 자세히 살펴보겠습니다.

주요 구성 요소

1. 상태 관리

class _DateSelectorState extends State<DateSelector> {
  late DateTime _selectedDate;
  late dynamic _periodType;

  @override
  void initState() {
    super.initState();
    _selectedDate = widget.selectedDate;
    _periodType = widget.periodType;
  }
}

_selectedDate와 _periodType은 위젯의 핵심 상태입니다. initState()에서 초기화됩니다.

2. 날짜 증가/감소 로직

void _incrementDate() {
  setState(() {
    final now = DateTime.now();
    if (_periodType == 0 || _periodType == 'daily') {
      final newDate = _selectedDate.add(const Duration(days: 1));
      if (newDate.isBefore(now.add(const Duration(days: 1)))) {
        _selectedDate = newDate;
      }
    } else if (_periodType == 1 || _periodType == 'weekly') {
      final currentWeekStart = _selectedDate.subtract(Duration(days: _selectedDate.weekday % 7));
      final nextWeekStart = currentWeekStart.add(const Duration(days: 7));
      if (nextWeekStart.isBefore(now)) {
        _selectedDate = nextWeekStart;
      } else {
        _selectedDate = now.subtract(Duration(days: now.weekday % 7));
      }
    } else if (_periodType == 2 || _periodType == 'monthly') {
      final newDate = DateTime(_selectedDate.year, _selectedDate.month + 1, 1);
      if (newDate.isBefore(DateTime(now.year, now.month, now.day + 1))) {
        _selectedDate = newDate;
      }
    }
    widget.onDateChanged(_selectedDate);
  });
}

이 메서드는 선택된 날짜를 증가시킵니다. 주목할 점:

  • 일간/주간/월간 모드에 따라 다르게 동작합니다.
  • 현재 날짜를 넘어가지 않도록 체크합니다.
  • 주간 모드에서는 일요일을 기준으로 주를 계산합니다.

3. 날짜 증가 가능 여부 확인

bool canIncrementDate() {
  final now = DateTime.now();
  if (_periodType == 0 || _periodType == 'daily') {
    return _selectedDate.isBefore(now);
  } else if (_periodType == 1 || _periodType == 'weekly') {
    final currentWeekStart = _selectedDate.subtract(Duration(days: _selectedDate.weekday % 7));
    final nextWeekStart = currentWeekStart.add(const Duration(days: 7));
    return nextWeekStart.isBefore(now);
  } else if (_periodType == 2 || _periodType == 'monthly') {
    final nextMonth = DateTime(_selectedDate.year, _selectedDate.month + 1, 1);
    return nextMonth.isBefore(DateTime(now.year, now.month, 1));
  }
  return false;
}

이 메서드는 날짜를 더 증가시킬 수 있는지 확인합니다. UI에서 버튼의 활성화 여부를 결정하는 데 사용됩니다.

4. UI 구성

@override
Widget build(BuildContext context) {
  return Row(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      IconButton(
        icon: const Icon(FluentIcons.caret_left_24_filled),
        color: const Color(0xff9CA4AC),
        iconSize: 20,
        padding: EdgeInsets.zero,
        onPressed: _decrementDate,
      ),
      const SizedBox(width: 10),
      Text(
        FormatterUtil.formatSelectedDate(_selectedDate, _periodType),
        style: const TextStyle(
          fontFamily: 'Pretendard',
          fontSize: 15,
          color: Color(0xff9CA4AC),
          fontWeight: FontWeight.w500,
          letterSpacing: -0.2,
        ),
      ),
      IconButton(
        icon: const Icon(FluentIcons.calendar_24_regular),
        iconSize: 20,
        onPressed: () => _pickDate(context),
      ),
      IconButton(
        icon: const Icon(FluentIcons.caret_right_24_filled),
        iconSize: 20,
        onPressed: canIncrementDate() ? _incrementDate : null,
        color: canIncrementDate() ? const Color(0xff9CA4AC) : const Color(0xff818990),
      ),
    ],
  );
}

UI는 간단한 Row 위젯으로 구성됩니다:

  • 왼쪽 화살표 (날짜 감소)
  • 현재 선택된 날짜 텍스트
  • 달력 아이콘 (날짜 직접 선택)
  • 오른쪽 화살표 (날짜 증가)

주목할 점은 오른쪽 화살표의 onPressed와 color 속성입니다. canIncrementDate()의 결과에 따라 동적으로 설정됩니다.

결론

이 DateSelector 위젯은 다음과 같은 장점을 제공합니다:

  1. 직관적인 UI로 사용자가 쉽게 날짜를 탐색할 수 있습니다.
  2. 일간/주간/월간 모드를 지원하여 다양한 형태의 데이터 조회에 적합합니다.
  3. 현재 날짜를 넘어가지 않도록 하여 미래의 데이터 접근을 방지합니다.
  4. 동적인 UI 업데이트로 사용자에게 시각적 피드백을 제공합니다.
저작자표시 (새창열림)
    mark340
    mark340
    착하게삽시다

    티스토리툴바