Flutter 개발일지 day 6

customContainer 추가

이전에는 모든 날짜들을 담는 container들은 그냥 기본 container에 child로 text를 갖는 형태였다. 따라서 확장성이 아예 없고, 한 번 기능을 추가할 때마다 42개 모두 반복해줘야하는(…) 문제가 생기기 때문에 확장성을 위해 새로 customContainer를 정의했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// customContainer.dart
lass EveryDay extends StatefulWidget {
  final Cursor cursor;
  final DateTime oneDay;
  final bool isSchedule = false; //일정 존재여부 관련 변수
  const EveryDay(this.cursor, this.oneDay, {Key? key}) : super(key: key);

  @override
  State<EveryDay> createState() => _EveryDayState();
}

class _EveryDayState extends State<EveryDay> {

  @override
  Widget build(BuildContext context) {
    return Expanded(child: GestureDetector(
      onTap: (){
        setState(() {
          widget.cursor.selected = widget.oneDay;
        });
      },
      child: Container(
        padding: const EdgeInsets.fromLTRB(0, 4, 0, 10),
        height: 50,
        child: widget.oneDay.month != widget.cursor.selected.month ? null : Stack(
          children: [
            Positioned(
                // left: 0.95,
                child: Container(
                    height: 20,
                    width: 20,
                    decoration: const BoxDecoration(
                      color: Color(0xFFBBDED6),
                      shape: BoxShape.circle,
                    )
                )
            ),
            Positioned(
              top: 1,
              height: 15,
              width: 20,
              child: MyText(widget.oneDay.day.toString(), 15),
            ),
            Positioned(
                top: 5,
                left: 25,
                child: Container(
                  height: 7,
                  width: 7,
                  decoration: const BoxDecoration(
                    color: Color(0xFFFFB6B9),
                    shape: BoxShape.circle,
                  )
                )
            ),
          ],
        )
      ),

이 위젯은 cursor 위치나 일정 여부에 따라 변할 수 있으므로, 나중을 생각해서 미리 stateful로 구현했다. 인자로 현재 커서 위치를 알기 위해서 cursor을 받고, container가 가르킬 날짜를 알려주는 daylist[i]를 담을 oneDay를 받는다. Expanded는 예전에 까먹고 설명 안 한거 같은데 월~일 표시할 때랑 동일하게 좌우로 이쁘게 알아서 비율 잡게 써줬다. 그 아래 GestureDetector는 해당 컨테이너를 클릭(tap)했을 때, 지금 커서에 이 container의 날짜를 대입해준다.

Stack을 쓴 이유는 Positioned를 쓰기 위해서이고, Positioned를 쓴 이유는 말그대로 동그라미를 원하는 위치에 뙇 배치하고 싶어서이다.

  1. 첫번째 Positioned : 커서가 해당 날짜 위에 있는지 알려준다. **가장 맨 처음에 쓴 이유는 Stack은 앞에서부터 위로 쌓이기 때문에, 숫자를 이 원 위에 올리고 싶어서 먼저 썼다.
  2. 두번째 Positioned : container가 담고 있는 날짜를 표시해준다.
  3. 세번째 Positioned : 날짜 오른편에 위치해서 그 날에 일정이 존재하면 핑크색 동그라미를 띄운다. 현재는 month만 비교해서 그 달이 아니면 통째로 사라지게만 했고, 아직 일정 자체를 구현을 안했기 때문에 요건 나중에 조건을 넣을 예정이다.

디자인 변경

원래 월~일, 그리고 날짜들 싹다 중앙정렬시켰는데, 그랬더니 일정이 있을 때 띄우기로 한 동그라미를 배치할 곳이 없어서, crossAxisAlignment와 TextAlign을 모두 .center에서 .start로 바꾸었다. 그래서 전체적으로 텍스트가 살짝 왼쪽으로 치우친 형태가 되었다.

배운점

Positioned 써먹기. 예전에 시간표 만들때 Positioned를 써먹으려고 해봤는데 잘 이해가 안돼서 그냥 넘어갔던 기억이 있다. 그냥 써보니까 아주 직관적으로 쓸 수 있었다. 특히 Stack에 넣는 순서에 따라 앞에 오는지 뒤에 오는지가 달라진다는게 아주 직관적이라 만족했다.