728x90
2024.02.15 - [Flutter & Dart] - Flutter & Dart 디데이 & 가계부 앱 [러브페이] 만들기(2) - 파이어베이스
Flutter & Dart 디데이 & 가계부 앱 [러브페이] 만들기(2) - 파이어베이스
https://dongkyu.tistory.com/50 Flutter & Dart 디데이 & 가계부 앱 [러브페이] 만들기(1) - 바텀네비게이션 디데이, 가계부가 합쳐진 앱을 만들고자 한다. 앱 이름은 러브페이 라고 지었다. 앱은 홈(디데이),
dongkyu.tistory.com
지난 글에 이어 이번엔 디데이 탭의 플러터 소스를 작성 할 것이다.
사진과 같은 형태의 디데이 리스트를 만들 것이다.
1. 디데이 만들기
Scaffold(
appBar: AppBar(
centerTitle: false,
title: Row(
children: [
const Icon(Icons.star_rate, size: 25),
const SizedBox(width: 10),
Text('The D-Day Memorys', style: AppTextStyle().blackBold18),
],
),
),
body: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: SafeArea(
child: Stack(
children: [
Column(
children: [
Expanded(
child: Container(
height: Get.height,
padding: const EdgeInsets.all(15),
child: myList()),
),
],
),
Positioned(
right: 20,
bottom: 20,
child: InkWell(
onTap: () {
Get.to(() => const Page1Input(
date: '', documentId: '', subject: ''));
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: AppColors().titleColor),
width: 50,
height: 50,
child: Center(
child: Icon(
Icons.add,
color: AppColors().colorwhite,
)),
),
))
],
),
),
));
추가 버튼은 스크롤이 이동되어도 하단에 고정되어야 하기 때문에 스택 + 포지션으로 위치를 설정 했다.
Widget myList() {
return SingleChildScrollView(
child: Column(
children: [
Obx(
() => ListView.builder(
shrinkWrap: true,
physics: const ScrollPhysics(),
itemCount: controller.ddaySearch.length,
itemBuilder: (context, index) {
return InkWell(
onTap: () {
Get.to(() => Page1Input(
subject: controller.ddaySearch[index].subject,
date: controller.ddaySearch[index].date,
documentId: controller.ddaySearch[index].id,
));
},
child: Container(
margin: const EdgeInsets.symmetric(vertical: 10),
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(
width: 1,
),
color: AppColors().colorwhite,
borderRadius: BorderRadius.circular(5),
),
height: 100,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Text(
controller.ddaySearch[index].subject,
style: AppTextStyle().black16,
),
),
InkWell(
onTap: () {
showDialog(
context: context,
builder: (context) => DeletePop(
text: '해당 기념일을 삭제하시겠습니까?',
callback: () async {
await controller.delData(controller
.ddaySearch[index].id);
Get.back();
}));
},
child: const Icon(Icons.delete, weight: 20))
],
),
Text(
'${controller.ddaySearch[index].date} (${controller.getDayKor(controller.ddaySearch[index].date)})',
style: AppTextStyle().color99999914),
const Spacer(),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
controller.getDateDifference(
controller.ddaySearch[index].date) <
0
? Text(
'D - ${controller.getDateDifference(controller.ddaySearch[index].date) * -1} ',
style: AppTextStyle().blackBold22,
)
: Text(
'D + ${controller.getDateDifference(controller.ddaySearch[index].date)}',
style: AppTextStyle().blackBold22,
),
],
)
],
),
),
);
},
),
),
],
),
);
}
휴지통 이미지를 클릭 시 해당 디데이를 삭제 하기 위해 showDialog를 이용해 DeletePop 위젯을 호출 하였다.
DeletePop은 팝업창에 적을 메시지, 확인 버튼 클릭 시 행동 할 이벤트를 받으며 취소 버튼을 클릭 시 팝업창을 닫는다.
class DeletePop extends StatelessWidget {
const DeletePop({super.key, required this.text, required this.callback});
final String text;
final Function() callback;
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Center(
child: Text(
text,
style: AppTextStyle().blackBold18,
),
),
buttonPadding: const EdgeInsets.all(0),
backgroundColor: AppColors().colorwhite,
actions: <Widget>[
ClipRRect(
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(5),
bottomRight: Radius.circular(5),
),
child: Row(
children: [
Flexible(
fit: FlexFit.tight,
child: GestureDetector(
onTap: () {
Get.back();
},
child: Container(
height: 50,
decoration: BoxDecoration(
color: AppColors().colorwhite,
border: Border(
top: BorderSide(
color: AppColors().coloreeeeee,
width: 1.0,
),
),
),
child: Center(
child: Text(
'취소',
style: AppTextStyle().color19191918bold,
),
),
),
),
),
Container(
color: AppColors().coloreeeeee,
width: 1,
height: 50,
),
Flexible(
fit: FlexFit.tight,
child: GestureDetector(
onTap: () async {
await callback();
},
child: Container(
height: 50,
decoration: BoxDecoration(
color: AppColors().colorwhite,
border: Border(
top: BorderSide(
color: AppColors().coloreeeeee,
width: 1.0,
),
),
),
child: Center(
child: Text(
'확인',
style: AppTextStyle().blackBold18,
),
),
),
),
),
],
),
)
],
);
}
}
getDateDifference는 오늘부터 특정 일자 까지의 차이를 구한다.
int getDateDifference(String date) {
var split = date.split('-');
DateTime targetDate =
DateTime(int.parse(split[0]), int.parse(split[1]), int.parse(split[2]));
DateTime today = DateTime.now();
int differenceInDays = today.difference(targetDate).inDays;
return differenceInDays;
}
DateTime.now() 는 현 시간을 구하는 것이고 현재.difference(비교일시).inDays 는 현재 - 비교일시 의 일자를 구하는 것이다.
해당 결과가 0보다 크면 D +, 0 보다 작으면 D - 를 위해 사용 하였다.
728x90
'Flutter & Dart' 카테고리의 다른 글
[Flutter]플러터 디데이 & 가계부 앱 [러브페이] 만들기(4) - 가계부 (0) | 2024.02.22 |
---|---|
[Flutter]플러터 달력 만들기 (0) | 2024.02.20 |
[Flutter]플러터 디데이 & 가계부 앱 [러브페이] 만들기(2) - 파이어베이스 (0) | 2024.02.15 |
[Flutter]플러터 디데이 & 가계부 앱 [러브페이] 만들기(1) - 바텀네비게이션 (1) | 2024.02.15 |
Flutter & Dart 구글 애드몹 광고 추가하기 2. 개발하기 (0) | 2024.01.25 |