Flutter 개발일지 day 10

Hive box 구현!

1. scheduleClass.dart 수정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@HiveType(typeId: 1)
class ScheduleClass{
  @HiveField(0)
  String name; // 일정 이름
  @HiveField(1)
  bool alarm; // 알림 여부
  @HiveField(2)
  DateTime date; // 일정 날짜 및 시간 저장
  @HiveField(3)
  bool btime; // 시간 존재 여부
  @HiveField(4)
  bool done; // 일정 해결 여부
  
  //나머지 생략 ...
}

먼저 우리가 hive에 전달할 class 중에서 우리가 자체적으로 define한 클래스가 있기 때문에, 이를 hive에서 인지할 수 있도록 adapter에서 처리할 수 있게 해야한다고 한다. 그래서 이 클래스에 @(at sign)로 metadata annotation을 준다고 하는데 솔직히 잘 이해하고 적용한건 아니다…

아무튼 @를 이용해서 위에 코드처럼 각자 field를 주고 class 전체에 typeId를 할당하고, flutter pub run build_runner build를 실행하면 scheduleClass.g.dart 파일이 알아서 생성된다. 이 파일에 ScheduleClassAdapter가 선언되어 있으며, 이 파일은 함부로 수정하면 안된다!

2. main.dart 수정

1
2
3
// void main()
Hive.registerAdapter(ScheduleClassAdapter());
await Hive.openBox<List<ScheduleClass>>('lib');

위에서 생성한 ScheduleClassAdapter를 여기서 실행한다.

3. monthCal.dart 수정 (일정 추가 버튼 구현)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Scaffold의 body 부분
body : ValueListenableBuilder(
  valueListenable: Hive.box<List<ScheduleClass>>('lib').listenable(),
  builder: (context, Box<List<ScheduleClass>> box, child) {
    return Column(
      children: [
        //... 중간 일자 widget들 생략

        FloatingActionButton(
          onPressed: () async{
            box.clear();
            int i = 0;
            if(!box.containsKey('2022.12.25')) {
              box.put("2022.12.25", []);
              box.get("2022.12.25")!.add(ScheduleClass(name: "t$i", date: DateTime.now()));
            }
            else
              box.get("2022.12.25")!.add(ScheduleClass(name: "t$i", date: DateTime.now()));
            i++;
            print(box.get("2022.12.25"));
          },
        ),
      ]
    );

원래 body에 바로 Column이 왔었는데, 이를 ValueListenableBuilder로 감싸면 특정 value에 대해서 그 value가 변하면 아래 widget들을 다시 build해준다! 우리가 원하는 형태는 (일단은)FloatingActionButton으로 hiveBox에 값을 대입하면 달력에서 우리가 추가한 일정을 보여주는 형태였다.

FloatingAcctionButton을 보면, 눌렀을 때 먼저 box가 특정 일자 값을 가지고 있는 지 먼저 test한다(여기서는 2022.12.25). 그 값이 없다면 먼저 box.put으로 그 날짜를 key 값 삼아 빈 리스트를 넣고, 다시 그 리스트를 box.get으로 불러와서 add해준다. 그 값이 존재하면(=else) box.get으로 그 날짜를 key값 삼아 벌러와서 add 해준다. 그리고 print를 통해 그 날짜를 key 값으로 가진 list를 모두 출력한다.

이 상태로 test 해보면 아무 문제 없이 잘 작동한다. 위에서 box.clear를 주석 처리해놓고 계속 누르면 하나씩 늘어나면서 잘 출력된다. hivebox의 좋은 점은 어플을 아예 껐다가 켜도 내부에 잘 저장이 되어있다는 점이다. element가 2개 있는 상테에서 껐다 키고 다시 누르면 3개부터 출력해준다.

배운점

hivebox를 구현하려면 생각보다 시간이 훨씬 더 많이 들 줄 알았는데, 예상보다는 더 빨리 구현에 성공해서 감격스러웠다… 그렇지만 아직은 calender 상에 추가한게 아니라 아래 print하는 것만 성공했기 때문에, 우리가 설계한대로 hive의 변화에 따라서 widget이 다시 build될지는 좀 더 지켜봐야할 것 같다. 제대로 배운 건 아니지만, navermap api에서 삽질할 때 발견한 .g.dart 파일이 뭐를 위해 만들어진 파일인지 대충 배웠다!