[Flutter 8일차] 일정 등록 기능과 DB 연동

ttt00·2026년 5월 11일

Flutter

목록 보기
9/11

오늘의 목표 : 일정 등록 기능 추가와 Flutter에서 DB연동하기

핵심 개념

Stream을 사용하면 DB값이 바뀌면 화면도 자동 갱신된다
Drift는 Flutter에서 SQLite를 쉽게 관리하는 라이브러리이다.
LazyDatabase를 사용하면 DB를 필요할때만 열어서 성능이 최적화된다.

수업 코드

/component/schedult_bottom_sheet.dart

import 'package:flutter/material.dart';
import 'package:calendar_scheduler/const/colors.dart';
import 'package:calendar_scheduler/component/custom_text_field.dart';

class ScheduleBottomSheet extends StatefulWidget{
  const ScheduleBottomSheet({Key? key}) : super(key:key);

  
  State<ScheduleBottomSheet> createState() => _ScheduleBottomSheetState();
}

class _ScheduleBottomSheetState extends State<ScheduleBottomSheet> {
  
  Widget build(BuildContext context) {
    //키보드 높이 가져오기
    final bottomInset = MediaQuery.of(context).viewInsets.bottom;
    //viewInsets : 시스템이 차지하는 화면의 bottom: 아랫부분 크기를 알수 있음

    return SafeArea(
        child: Container(
          // MediaQuery : SafeArea에 화면의 반 차지하는 컨테이너 위젯을 배치
          height: MediaQuery.of(context).size.height/2 + bottomInset,
          color: Colors.white,
          child: Padding(
              padding: EdgeInsets.only(left:8, right:8, top:8),
            child: Column(
              children: [
                Row(
                  children: [
                    Expanded(
                      child: CustomTextField(
                        label: '시작시간',
                        isTime: true,
                      ),
                    ),
                    const SizedBox(width: 16),
                    Expanded(
                      child: CustomTextField(
                        label: '종료시간',
                        isTime: true,
                      ),
                    ),
                    const SizedBox(width: 16),
                  ],
                ),
                SizedBox(height: 8),
                Expanded(
                  child: CustomTextField(
                      label: '내용',
                      isTime: false
                  ),
                ),
              ],
            ),
          ),
        ),
    );
  }
}

=> 사용자가 일정을 입력할 수 있도록 시작시간, 종료 시간, 내용을 입력받는 하단 창을 만드는 코드이다

/database/drift_database.dart

import 'package:calendar_scheduler/model/schedule.dart';
import 'package:drift/drift.dart';

import 'package:drift/native.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
import 'dart:io';

part 'drift_database.g.dart';

(
  tables:[
    Schedules,
  ],
)

class LocalDatabase extends _$LocalDatabase {
  LocalDatabase():super(_openConnection());

  Stream<List<Schedule>> watchSechdules(DateTime date) =>
      (select(schedules).. where((tbl) => tbl.date.equals(date))).watch();

  Future<int> createSchedule(SchedulesCompanion data) =>
      into(schedules).insert(data);

  Future<int> removeSchedule(int id) =>
      (delete(schedules)..where((tbl)=>tbl.id.equals(id))).go();

  
  int get schemaVersion => 1;
}

LazyDatabase _openConnection(){
  return LazyDatabase(() async{
    final dbFolder = await getApplicationCacheDirectory();
    final file = File(p.join(dbFolder.path, 'db.sqlite'));
    return NativeDatabase(file);
  });
}

=> Drift 데이터베이스로 일정 데이터를 저장, 조회, 삭제하고 DB 파일을 생성하는 코드이다.

/model/schedule.dart

import 'package:drift/drift.dart';

class Schedules extends Table {
  IntColumn get id => integer().autoIncrement()();
  TextColumn get content => text()();
  DateTimeColumn get date => dateTime()();
  IntColumn get startTime => integer()();
  IntColumn get endTime => integer()();

}

일정 테이블을 만드는 코드

코드 분석

/component/schedult_bottom_sheet.dart

Widget build(BuildContext context) {
    //키보드 높이 가져오기
    final bottomInset = MediaQuery.of(context).viewInsets.bottom;
    //viewInsets : 시스템이 차지하는 화면의 bottom: 아랫부분 크기를 알수 있음

    return SafeArea(
        child: Container(
          // MediaQueㄴry : SafeArea에 화면의 반 차지하는 컨테이너 위젯을 배치
          height: MediaQuery.of(context).size.height/2 + bottomInset,
          color: Colors.white,
          child: Padding(
              padding: EdgeInsets.only(left:8, right:8, top:8),
            child: Column(
              children: [
                Row(
                  children: [
                    Expanded(
                      child: CustomTextField(
                        label: '시작시간',
                        isTime: true,
                      ),
                    ),
                    const SizedBox(width: 16),
                    Expanded(
                      child: CustomTextField(
                        label: '종료시간',
                        isTime: true,
                      ),
                    ),
                    const SizedBox(width: 16),
                  ],
                ),
                SizedBox(height: 8),
                Expanded(
                  child: CustomTextField(
                      label: '내용',
                      isTime: false
                  ),
                ),
              ],
            ),
          ),
        ),
    );
  }
코드역할비고
MediaQuery.of(context).viewInsets.bottom키보드 높이 보기화면에 아랫부분 크기를 알 수 있음
Expanded입력창 크기 분배
SafeArea안전 영역 확보

/database/drift_database.dart

class LocalDatabase extends _$LocalDatabase {
  LocalDatabase():super(_openConnection());

  Stream<List<Schedule>> watchSechdules(DateTime date) =>
      (select(schedules).. where((tbl) => tbl.date.equals(date))).watch();

  Future<int> createSchedule(SchedulesCompanion data) =>
      into(schedules).insert(data);

  Future<int> removeSchedule(int id) =>
      (delete(schedules)..where((tbl)=>tbl.id.equals(id))).go();

  
  int get schemaVersion => 1;
}

LazyDatabase _openConnection(){
  return LazyDatabase(() async{
    final dbFolder = await getApplicationCacheDirectory();
    final file = File(p.join(dbFolder.path, 'db.sqlite'));
    return NativeDatabase(file);
  });
}
코드역할
Stream바뀐 DB값 화면에 적용
LazyDatabaseDB 필요할 때만 열어서 사용
Future나중에 줄 결과값
schemaVersion데이터베이스 구조의 버전을 관리하는 값

/model/schedule.dart

import 'package:drift/drift.dart';

class Schedules extends Table {
  IntColumn get id => integer().autoIncrement()();
  TextColumn get content => text()();
  DateTimeColumn get date => dateTime()();
  IntColumn get startTime => integer()();
  IntColumn get endTime => integer()();

}

=> DB테이블 설계, 생성

코드역할
autoIncrement()자동 증가

새로 알게된 것

Flutter에서 DB를 생성할 때의 SQL문법을 새로 알게 되었다

결과물

1개의 댓글

comment-user-thumbnail
2026년 5월 14일

사진이 인상적이네요. 너무너무 굿굿~~

답글 달기