Flutter로 To-Do 리스트 앱의 캘린더 이벤트 동기화 문제 해결하기 (앱 재실행 시 캘린더 일자에 마커 표시가 안되는 오류 개선)

2024. 12. 23. 12:14같이 공부합시다 - Flutter/Flutter로 To-Do 앱 만들기

728x90
반응형

 
Flutter로 To-Do 리스트 앱을 개발하다 보면,
캘린더에서 할 일이 있는 날짜에 마커(점)가
표시되지 않는 문제를 겪을 수 있어요. 😅
 
지난 시간에 진행했던 Flutter로 To-Do 리스트 앱 개선하기: 캘린더에 이벤트 표시하기 

Flutter로 To-Do 리스트 앱 개선하기: 캘린더에 이벤트 표시하기

우리 To-Do 리스트 앱에서는 현재 캘린더와,캘린더 일자에 연결된 할 일 까지만 볼 수 있죠. 캘린더에 할 일이 있는 날짜에 점을 표시하는 기능 또한사용자 경험(UX)을 크게 향상시킬 수 있어요. 이

steadybuilder.tistory.com

에서, 중요한 부분이 빠져 캘린더 날짜에 마커가 표시되지 않는 문제를 제가 겪게 되었습니다. 🤣

앱을 껐다가 다시 켰더니 캘린더 일자에 마커 표시가 안되더군요. 😱😱😱
 
이번 글에서는 캘린더와 할 일 데이터 동기화 문제를 파악하고, 이를 해결하는 방법을 다룰게요.
함께 문제를 해결하고, 앱의 완성도를 한 단계 높여봐요! 😊
 
<동기화 문제로 당황하는 스테디빌더>

동기화 문제로 당황하는 스테디빌더


 
 
 


문제 원인

  1. _calendarEvents와 todoList가 분리 관리:
    • todoList는 로컬에 저장되지만, _calendarEvents는 앱 실행 중에만 유지됩니다.
    • 따라서 앱을 다시 실행하면 _calendarEvents가 초기화되어 기존 데이터가 반영되지 않습니다.
  2. 동기화 부족:
    • todoList를 로드할 때 _calendarEvents를 업데이트하지 않아 데이터 불일치가 발생합니다.

 
 
 


해결 방법

1. _calendarEvents를 로컬에 저장하고 로드

SharedPreferences를 사용해 _calendarEvents를 저장하고, 앱 실행 시 다시 로드할 수 있도록 구현합니다.

 

_saveCalendarEvents 메서드 추가

Future<void> _saveCalendarEvents() async {
  final prefs = await SharedPreferences.getInstance();
  final jsonEvents = _calendarEvents.map((key, value) =>
    MapEntry(key.toIso8601String(), value));
  await prefs.setString('calendarEvents', jsonEncode(jsonEvents));
}

 

_loadCalendarEvents 메서드 추가

Future<void> _loadCalendarEvents() async {
  final prefs = await SharedPreferences.getInstance();
  final jsonString = prefs.getString('calendarEvents');
  if (jsonString != null) {
    final Map<String, dynamic> jsonEvents = jsonDecode(jsonString);
    setState(() {
      _calendarEvents.clear();
      jsonEvents.forEach((key, value) {
        _calendarEvents[DateTime.parse(key)] = List<String>.from(value);
      });
    });
  }
}

 
 
 
 
 
 


2. 앱 초기화 시 데이터 로드

initState에서 todoList와 _calendarEvents를 로드합니다.

@override
void initState() {
  super.initState();
  _loadTodoList();
  _loadCalendarEvents();
}

 
 
 
 
 
 


3. todoList와 _calendarEvents 동기화

 

_loadTodoList 수정

todoList를 로드한 후 _calendarEvents를 동기화합니다.

Future<void> _loadTodoList() async {
  final prefs = await SharedPreferences.getInstance();
  final jsonString = prefs.getString('todoList');
  if (jsonString != null) {
    final List<dynamic> jsonData = jsonDecode(jsonString);
    setState(() {
      _todoList.clear();
      _todoList.addAll(jsonData.cast<Map<String, dynamic>>());

      // _calendarEvents 동기화
      _calendarEvents.clear();
      for (var item in _todoList) {
        final dateKey = _normalizeDate(DateTime.parse(item['date']));
        _calendarEvents[dateKey] = _calendarEvents[dateKey] ?? [];
        _calendarEvents[dateKey]!.add(item['task']);
      }
    });
  }
}

 
 
 
 
 
 


4. 할 일 추가/삭제 시 _calendarEvents 업데이트

 

할 일 추가

void _addTodoItem(String task) {
  final today = DateTime.now();
  final dateKey = _normalizeDate(today);

  setState(() {
    _todoList.add({
      'task': task,
      'isCompleted': false,
      'date': today.toIso8601String(),
    });
    _calendarEvents[dateKey] = _calendarEvents[dateKey] ?? [];
    _calendarEvents[dateKey]!.add(task);
  });

  _saveTodoList();
  _saveCalendarEvents();
}

 

할 일 삭제

void _deleteTodoItem(int index) {
  final todoItem = _todoList[index];
  final dateKey = _normalizeDate(DateTime.parse(todoItem['date']));

  setState(() {
    _todoList.removeAt(index);
    _calendarEvents[dateKey]?.remove(todoItem['task']);
    if (_calendarEvents[dateKey]?.isEmpty ?? true) {
      _calendarEvents.remove(dateKey);
    }
  });

  _saveTodoList();
  _saveCalendarEvents();
}

 
 
 
 
 
 


5. 캘린더 마커 표시 확인

캘린더의 markerBuilder에서 _calendarEvents를 활용해 점을 표시합니다.

calendarBuilders: CalendarBuilders(
  markerBuilder: (context, day, events) {
    final eventList = _getEventsForDay(day);
    if (eventList.isNotEmpty) {
      return Positioned(
        bottom: 1,
        child: Container(
          width: 8.0,
          height: 8.0,
          decoration: const BoxDecoration(
            color: Colors.redAccent,
            shape: BoxShape.circle,
          ),
        ),
      );
    }
    return null;
  },
),

 
 
 
 
 
 


결과

  1. 앱 재실행 시 데이터 유지:
    • _todoList와 _calendarEvents가 모두 로컬에 저장되어 앱 재실행 후에도 유지됩니다.
  2. 캘린더 마커 표시:
    • _calendarEvents와 동기화된 데이터를 사용해 이벤트가 있는 날짜에 점이 표시됩니다.
  3. 데이터 일관성 유지:
    • 할 일 추가/삭제 시 _todoList와 _calendarEvents가 항상 동기화됩니다.

<문제 해결된 결과 화면 >
이제 앱을 재실행해도 할일 있는 날짜에 마커가 표시된다.
 

캘린더 모달 내 할일 있는 날짜에 마커가 표시된다.


 
 
 
 


결론

이번 글에서는 Flutter To-Do 리스트 앱에서 캘린더와 할 일 데이터의 동기화를 구현하고, 기존 데이터가 반영되지 않는 문제를 해결했어요.

이런 과정을 통해 앱의 완성도와 사용자 경험을 높일 수 있답니다. 😊 (저 역시 조금 더 발전된 느낌이네요. 여러분은 어떠신가요? ㅎㅎ)
 
다음 글에서는 정말로 캘린더에서 선택한 날짜의 할 일을 상세히 표시하는 방법에 대해 공유할 예정이에요.

궁금한 점이나 추가로 다루고 싶은 내용이 있다면 댓글로 남겨주세요!
 
함께 더 나은 앱을 만들어 봅시다! 💡
 
 
 
 

728x90
반응형