[flutter] 플러터 RxDart를 사용한 캘린더 및 일정 관리 기능 구현

목차

소개

이번 포스트에서는 RxDart를 사용하여 플러터 앱에 캘린더 및 일정 관리 기능을 구현하는 방법에 대해 알아보겠습니다. RxDart는 플러터와 함께 사용되는 라이브러리로, 반응형 프로그래밍에 특화되어 있어 유연하고 효율적인 코드 작성을 가능하게 합니다.

RxDart란?

RxDart는 플러터와 다트 언어에서 사용할 수 있는 반응형 프로그래밍 라이브러리입니다. 다트의 Stream 클래스를 더 쉽게 다룰 수 있도록 도와주며, Observable, Subject, StreamTransformer 등 다양한 기능을 제공합니다. RxDart의 사용을 통해 데이터 흐름을 좀 더 직관적이고 관리하기 쉽게 할 수 있습니다.

캘린더 UI 구성

먼저, RxDart를 사용하여 캘린더 UI를 구성해보겠습니다. 캘린더 UI는 GridView와 ListTile을 활용하여 각 날짜를 표시하고, 일정을 탭하면 일정 상세 페이지로 이동하는 방식으로 구현할 것입니다.

import 'package:flutter/material.dart';
import 'package:rxdart/subjects.dart';

class CalendarPage extends StatefulWidget {
  @override
  _CalendarPageState createState() => _CalendarPageState();
}

class _CalendarPageState extends State<CalendarPage> {
  BehaviorSubject<DateTime> selectedDateSubject = BehaviorSubject<DateTime>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('캘린더'),
      ),
      body: GridView.builder(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 7,
        ),
        itemCount: 365,
        itemBuilder: (context, index) {
          final date = DateTime.now().add(Duration(days: index));
          final isSelected = selectedDateSubject.value == date;

          return ListTile(
            title: Text(
              '${date.month}/${date.day}',
              style: TextStyle(
                fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
              ),
            ),
            onTap: () {
              selectedDateSubject.add(date);
              // 일정 상세 페이지로 이동 처리
            },
          );
        },
      ),
    );
  }

  @override
  void dispose() {
    selectedDateSubject.close();
    super.dispose();
  }
}

위 코드에서는 CalendarPage 클래스를 생성하여 캘린더 UI를 구성하였습니다. selectedDateSubject는 현재 선택된 날짜를 관리하기 위한 BehaviorSubject입니다. GridView의 itemBuilder에서 각 날짜를 ListTile로 표시하고, 선택된 날짜는 Bold로 표시되도록 구현했습니다. onTap 이벤트에서는 선택된 날짜를 selectedDateSubject에 추가하고, 일정 상세 페이지로 이동하는 처리를 할 수 있습니다.

일정 추가 및 삭제

다음으로, RxDart를 활용하여 일정을 추가 및 삭제할 수 있는 기능을 구현해보겠습니다. 예를 들어, 사용자가 일정을 추가하면 해당 날짜의 일정 목록에 추가되고, 삭제하면 목록에서 제거되는 방식으로 동작합니다.

import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';

class Schedule {
  final String title;
  final DateTime date;

  Schedule(this.title, this.date);
}

class CalendarPage extends StatefulWidget {
  @override
  _CalendarPageState createState() => _CalendarPageState();
}

class _CalendarPageState extends State<CalendarPage> {
  BehaviorSubject<DateTime> selectedDateSubject = BehaviorSubject<DateTime>();
  BehaviorSubject<List<Schedule>> scheduleListSubject = BehaviorSubject<List<Schedule>>.seeded([]);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('캘린더'),
      ),
      body: GridView.builder(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 7,
        ),
        itemCount: 365,
        itemBuilder: (context, index) {
          final date = DateTime.now().add(Duration(days: index));
          final isSelected = selectedDateSubject.value == date;

          return ListTile(
            title: Text(
              '${date.month}/${date.day}',
              style: TextStyle(
                fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
              ),
            ),
            subtitle: StreamBuilder<List<Schedule>>(
              stream: scheduleListSubject.stream,
              builder: (context, snapshot) {
                if (!snapshot.hasData) return Container();
                
                final schedules = snapshot.data!;
                final filtered = schedules.where((schedule) => schedule.date == date).toList();

                return Column(
                  children: filtered.map((schedule) => Text(schedule.title)).toList(),
                );
              },
            ),
            onTap: () {
              selectedDateSubject.add(date);
              // 일정 추가/삭제 처리
            },
          );
        },
      ),
    );
  }

  @override
  void dispose() {
    selectedDateSubject.close();
    scheduleListSubject.close();
    super.dispose();
  }
}

위 코드에서는 Schedule 클래스를 정의하여 일정을 저장하는 모델을 만들었습니다. scheduleListSubject는 현재 일정 목록을 관리하기 위한 BehaviorSubject입니다. ListTile의 subtitle 부분에서는 해당 날짜에 해당하는 일정 목록을 필터링하여 출력하도록 구현했습니다. onTap 이벤트에서는 선택된 날짜를 selectedDateSubject에 추가하고, 일정 추가/삭제 처리를 구현할 수 있습니다.

이제, RxDart를 사용하여 플러터 앱에 캘린더 및 일정 관리 기능을 구현하는 방법을 알아보았습니다. RxDart의 사용을 통해 데이터 흐름을 유연하고 효율적으로 관리할 수 있으며, 이를 활용하여 다양한 반응형 앱을 구현할 수 있습니다.

참고: RxDart 공식 문서 - https://pub.dev/documentation/rxdart/latest/