728x90
아래의 이미지와 같은 주차별 합계, 일자별 사용 금액을 포함한 달력을 만들 것이다.
table_calendar 라는 패키지가 있지만 해당 패키지는 주차별 합계를 지원하지 않는 것으로 알고 있다.
그래서 나는 직접 만든다..
1. 달력 컨트롤 생성
var week = ["일", "월", "화", "수", "목", "금", "토"];
요일은 배열에 따로 담아두었다.
insertDays(int year, int month) {
days.clear();
int lastDay = DateTime(year, month + 1, 0).day;
for (var i = 1; i <= lastDay; i++) {
days.add({
"year": year,
"month": month,
"day": i,
"inMonth": true,
});
}
if (DateTime(year, month, 1).weekday != 7) {
var temp = [];
int prevLastDay = DateTime(year, month, 0).day;
for (var i = DateTime(year, month, 1).weekday - 1; i >= 0; i--) {
temp.add({
"year": year,
"month": month - 1,
"day": prevLastDay - i,
"inMonth": false,
});
}
days = [...temp, ...days].obs;
}
var temp = [];
for (var i = 1; i <= 42 - days.length; i++) {
temp.add({
"year": year,
"month": month + 1,
"day": i,
"inMonth": false,
});
}
days = [...days, ...temp].obs;
}
년, 월, 일, 이번달 포함여부 체크하여 days에 포함 시켰다.
2. 달력 만들기
Widget canlendar() {
return SizedBox(
width: width,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
IconButton(
onPressed: () {
controller.previousMonth();
},
icon: Icon(Icons.arrow_back_ios,
size: 15, color: AppColors().color191919),
),
SizedBox(
child: Center(
child: Obx(
() => Text(
'${controller.month}월',
style: AppTextStyle().blackBold20,
),
),
),
),
IconButton(
onPressed: () {
controller.nextMonth();
},
icon: Icon(Icons.arrow_forward_ios,
size: 15, color: AppColors().color191919),
),
],
),
SizedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
for (var i = 0; i < controller.week.length; i++)
Text(
controller.week[i],
style: TextStyle(
color: i == 0
? Colors.red
: i == controller.week.length - 1
? Colors.blue
: Colors.black,
),
textAlign: TextAlign.center,
),
],
),
),
..........
],
),
);
}
상단의 < 1월 >을 위해 IconButton을 이용하여 버튼을 양쪽에 만들어 주었다.
그리고 일, 토요일은 색상 변경 해주었다.
Obx(
() => Container(
width: width,
child: Column(
children: [
calendarDay(0),
calendarDay(1),
calendarDay(2),
calendarDay(3),
calendarDay(4),
calendarDay(5),
],
),
),
)
calendarDay를 최대 6주차 까지 호출해주었다.
Widget calendarDay(int num) {
int iz = num * 7;
int yz = (num + 1) * 7;
RxBool dayCheck = false.obs;
for (var i = iz; i < yz; i++) {
if (controller.days[i]["inMonth"]) {
if (!dayCheck.value) {
dayCheck.value = true;
}
}
}
return dayCheck.value
? ........
calendarDay 는 아래의 달력의 1주씩 따로 만들기 위함이다.
6주를 호출하지만 만약 이번달이 5주만 있다면 그냥 넘어가기 위해서다.
for 를 이용하여 이번주에 이번달에 해당하는 일자가 있는지 체크한다.
return dayCheck.value
? Column(
children: [
Container(
padding: const EdgeInsets.only(right: 10),
width: width,
height: 20,
color: AppColors().colorf7f6f6,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
controller.getWeekSumMoney(num, '0'),
style: AppTextStyle().colortitle8,
),
controller.getWeekSumMoney(num, '1') != ''
? Container(
padding: const EdgeInsets.only(left: 10),
child: Text(
controller.getWeekSumMoney(num, '1'),
style: AppTextStyle().black8,
),
)
: Container(),
],
),
),
Row(
............
],
)
: Container();
이번주에 입금, 출금의 합계를 구하기 위하여 사용하였다.
getDaySumMoney는 이번 주에 gubn이 같은 것들의 합계를 보여준다.
String getDaySumMoney(String day, String gubn) {
int money = 0;
for (int i = 0; i < accountMonthSearch.length; i++) {
List<String> parts = accountMonthSearch[i].date.split('-');
DateTime reserDate = DateTime(
int.parse(parts[0]),
int.parse(parts[1]),
int.parse(parts[2]),
);
int year = int.parse(DateFormat('yyyy').format(isSelectedDay.value));
int month = int.parse(DateFormat('MM').format(isSelectedDay.value));
if (year == reserDate.year &&
month == reserDate.month &&
int.parse(day) == reserDate.day &&
accountMonthSearch[i].gubn == gubn) {
money = money + accountMonthSearch[i].money;
}
}
// accountMonthSearch
return money.toString().stringToNum() == '0'
? ''
: gubn == '0'
? '+${money.toString().stringToNum()}'
: '-${money.toString().stringToNum()}';
}
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
for (var i = iz; i < yz; i++)
controller.days[i]["inMonth"]
? Obx(
() => InkWell(
onTap: () async {
for (var j = 0;
j < controller.days.length;
j++) {
controller.days[j]["picked"].value = false;
}
controller.onDateSelected(
controller.days[i]["day"].toString());
},
child: Stack(
children: [
Container(
width: (width - 10) / 7,
height: 60,
padding: const EdgeInsets.only(top: 10),
child: Text(
controller.days[i]["day"].toString(),
style: controller.days[i]["day"] ==
controller.day.value
? AppTextStyle().blackBold16
: AppTextStyle().black14,
textAlign: TextAlign.center,
),
),
Positioned(
right: 1,
bottom: 5,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.end,
children: [
Text(
controller.getDaySumMoney(
controller.days[i]["day"]
.toString(),
'0'),
style: AppTextStyle().colortitle8,
),
Text(
controller.getDaySumMoney(
controller.days[i]["day"]
.toString(),
'1'),
style: AppTextStyle().black8,
),
],
),
)
],
),
),
)
: Container(
width: 30,
margin: const EdgeInsets.symmetric(
horizontal: 10, vertical: 20),
),
],
),
이번주에 해당 하는 일자를 표기한다.
선택된 일자는 bold체를 추가해 주었고, 입금, 출금 내역을 stack을 이용하여 추가하였다.
해당 소스들을 모두 적용하면 아래 사진과 같이 만들어진다.
728x90
'Flutter & Dart' 카테고리의 다른 글
[Flutter]플러터 AppLifecycleState, 라이프사이클 체크하기 (0) | 2024.03.21 |
---|---|
[Flutter]플러터 디데이 & 가계부 앱 [러브페이] 만들기(4) - 가계부 (0) | 2024.02.22 |
[Flutter]플러터 디데이 & 가계부 앱 [러브페이] 만들기(3) - 디데이 (0) | 2024.02.16 |
[Flutter]플러터 디데이 & 가계부 앱 [러브페이] 만들기(2) - 파이어베이스 (0) | 2024.02.15 |
[Flutter]플러터 디데이 & 가계부 앱 [러브페이] 만들기(1) - 바텀네비게이션 (1) | 2024.02.15 |