본문 바로가기

Flutter & Dart

[Flutter]플러터 디데이 & 가계부 앱 [러브페이] 만들기(4) - 가계부

반응형

2024.02.16 - [Flutter & Dart] - Flutter & Dart 디데이 & 가계부 앱 [러브페이] 만들기(3) - 디데이

 

Flutter & Dart 디데이 & 가계부 앱 [러브페이] 만들기(3) - 디데이

https://dongkyu.tistory.com/51 Flutter & Dart 디데이 & 가계부 앱 [러브페이] 만들기(2) - 파이어베이스 https://dongkyu.tistory.com/50 Flutter & Dart 디데이 & 가계부 앱 [러브페이] 만들기(1) - 바텀네비게이션 디데이,

dongkyu.tistory.com

지난 글에 이어 오늘은 가계부를 만들려고 한다.

가계부는 아래 사진과같이  상단의 월별 수입,지출,이체 합계, 달력, 하단의 일별 합계, 일별 사용내역으로 구성한다.

 

1. 기본 틀 만들기

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: false,
        title: Row(
          children: [
            const Icon(Icons.calendar_month_outlined, size: 25),
            const SizedBox(width: 10),
            Text('소비 캘린더', style: AppTextStyle().blackBold18),
          ],
        ),
      ),
      body: GestureDetector(
        onTap: () {
          FocusScope.of(context).unfocus();
        },
        child: SafeArea(
          child: Stack(
            children: [
              Column(
                children: [
                  Expanded(
                      child: ListView(
                    children: [
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          topData(),
                          Calendar(
                            width: Get.width,
                          ),
                          list(context),
                          const SizedBox(height: 50),
                        ],
                      )
                    ],
                  ))
                ],
              ),
              Positioned(
                  right: 20,
                  bottom: 20,
                  child: InkWell(
                    onTap: () {
                      Get.to(() => Page2Input(
                          date: calendarController.getSelectDay(),
                          cate: '',
                          cust: '',
                          memo: '',
                          gubn: '0',
                          mony: '',
                          documentId: ''));
                    },
                    child: Container(
                      decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(50),
                          color: AppColors().titleColor),
                      width: 50,
                      height: 50,
                      child: Center(
                          child: Icon(
                        Icons.add,
                        color: AppColors().colorwhite,
                      )),
                    ),
                  ))
            ],
          ),
        ),
      ),
    );
  }

 

기본적인 구성은 

상단의 월별 합계 : topData()

달력 : Calendar(),

하단 일별 내용 : list() 로 구성하였고, 오른쪽 아래의 + 버튼을 위해 Stack, Positioned를 사용해서 내용추가 버튼을 만들었다.

 

  Widget topData() {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 15),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  Text('수입 : + ', style: AppTextStyle().black14),
                  Obx(
                    () => Text(
                      '${calendarController.monthSumMoney.value.toString().stringToNum()}원',
                      style: AppTextStyle().black14,
                    ),
                  ),
                ],
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  Text('이체 : ', style: AppTextStyle().black14),
                  Obx(
                    () => Text(
                        '${calendarController.monthSumMoney3.value.toString().stringToNum()}원',
                        style: AppTextStyle().black14),
                  ),
                ],
              ),
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              Text('지출 : - ', style: AppTextStyle().black14),
              Obx(
                () => Text(
                    '${calendarController.monthSumMoney2.value.toString().stringToNum()}원',
                    style: AppTextStyle().black14),
              ),
            ],
          ),
        ],
      ),
    );
  }

 

topData() 는 월별 수입, 지출, 이체 내역을 출력해준다.

 

달력은 지난번에 만든 Calendar 위젯을 사용하였다.

2024.02.20 - [Flutter & Dart] - Flutter & Dart 주차별 합계를 포함한 달력 구현하기

 

Flutter & Dart 주차별 합계를 포함한 달력 구현하기

아래의 이미지와 같은 주차별 합계, 일자별 사용 금액을 포함한 달력을 만들 것이다. table_calendar 라는 패키지가 있지만 해당 패키지는 주차별 합계를 지원하지 않는 것으로 알고 있다. 그래서 나

dongkyu.tistory.com

  Widget list(BuildContext context) {
    return Obx(
      () => Container(
        padding: const EdgeInsets.symmetric(horizontal: 15),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const BlankRow(heigth: 1),
            const SizedBox(height: 5),
            Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: [
                        Text('수입 : ', style: AppTextStyle().black14),
                        Text(
                            '+ ${calendarController.sumMoney.value.toString().stringToNum()}원',
                            style: AppTextStyle().black14),
                      ],
                    ),
                    Row(
                      children: [
                        Text('이체 : ', style: AppTextStyle().black14),
                        Text(
                            '${calendarController.sumMoney3.value.toString().stringToNum()}원',
                            style: AppTextStyle().black14),
                      ],
                    ),
                  ],
                ),
                Row(
                  children: [
                    Text('지출 : ', style: AppTextStyle().black14),
                    Text(
                        '- ${calendarController.sumMoney2.value.toString().stringToNum()}원',
                        style: AppTextStyle().black14),
                  ],
                ),
              ],
            ),
            const SizedBox(height: 5),
            ListView.builder(
              shrinkWrap: true,
              physics: const NeverScrollableScrollPhysics(),
              itemCount: calendarController.accountSearch.length,
              itemBuilder: (context, index) {
                return InkWell(
                  onTap: () {
                    Get.to(() => Page2Input(
                        date: calendarController.getSelectDay(),
                        cate: calendarController.accountSearch[index].category,
                        cust: calendarController.accountSearch[index].customer,
                        memo: calendarController.accountSearch[index].memo,
                        gubn: calendarController.accountSearch[index].gubn,
                        mony: calendarController.accountSearch[index].money
                            .toString(),
                        documentId: calendarController
                            .accountSearch[index].documentId));
                  },
                  child: Column(
                    children: [
                      Container(
                        width: Get.width,
                        margin: const EdgeInsets.symmetric(vertical: 10),
                        padding: const EdgeInsets.all(5),
                        child: Row(
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
                            getIcon(
                                calendarController.accountSearch[index].gubn,
                                calendarController
                                    .accountSearch[index].category),
                            const SizedBox(width: 10),
                            Flexible(
                              child: Row(
                                mainAxisAlignment:
                                    MainAxisAlignment.spaceBetween,
                                children: [
                                  Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    children: [
                                      Text(
                                        calendarController
                                            .accountSearch[index].customer,
                                        style: AppTextStyle().black16,
                                      ),
                                      const SizedBox(height: 5),
                                      Text(
                                          '${calendarController.accountSearch[index].date} ${getName(calendarController.accountSearch[index].gubn, calendarController.accountSearch[index].category)}',
                                          style: AppTextStyle().color99999914),
                                      const SizedBox(height: 5),
                                      Text(
                                        calendarController
                                            .accountSearch[index].memo,
                                        style: AppTextStyle().color99999914,
                                      ),
                                    ],
                                  ),
                                  Text(
                                    '${calendarController.accountSearch[index].gubn == '0' ? '+ ' : calendarController.accountSearch[index].gubn == '1' ? '- ' : ''}${calendarController.accountSearch[index].money.toString().stringToNum()} 원',
                                    style: calendarController
                                                .accountSearch[index].gubn ==
                                            '0'
                                        ? AppTextStyle().colortitle16
                                        : AppTextStyle().black16,
                                  ),
                                ],
                              ),
                            ),
                          ],
                        ),
                      ),
                      BlankRow(heigth: 1)
                    ],
                  ),
                );
              },
            ),
          ],
        ),
      ),
    );
  }

 

list()는 ListView.builder를 이용하여 목록을 구성하였고, 클릭 시 가계부 내용 추가하는 화면을 열면서 데이터를 넘겨줘 수정할 수 있게 하였다.

 

반응형