목표
만난지 며칠이 지났는지 확인할 수 있는 날짜 앱을 만들어보자. 이를 응용하여 100, 200, 300, 1년, 2주년까지 확인할 수 있도록 확장해보자.
본 내용을 전현직 마케터이자 현직 개발자 및 지망생이 개인공부를 하면서 배운 내용을 정리해놓은 글입니다. 해당내용에 있어서 내용상의 문의 사항 혹은 코드상에 수정사항이 발견이 되면 알려주시면 감사하겠습니다. 같이 고민해보고 수정할 수 있도록 하겠습니다.
한국인이 좋아하는 결말 혹은 시작을 위해서 오늘까지 만든 내용을 먼저 보여드리겠다.
오늘까지의 완성품
- MyApp()을 만들어서 MaterialApp - Scaffold()로 반환하기
- 오늘 날짜를 표현
- Textformfield 내에 오늘의 날짜를 적을 수 있도록 표현
- 버튼 클릭시, 100, 200, 300일 그리고 1년을 표현할 수 있도록 기능 구현
뭔가 이렇게만 보면 초반에 만들고자 했던 기능은 전부 넣어버린 것 같지만, 이제 여기서 더 꾸밀 것은 아무래도
- 날짜 표현을 '간결하게' 표시하기
- '아이콘'등을 추가하기
- '사이드바'를 추가하여 메모 남기기
- 전체적인 UI 수정하기
그럼 지금까지의 전체 코드는 어떨까? 사실 이번까지 만드는데 큰 어려움은 없었다. 혼자서 만들어보다가 계산을 하거나 수식이 막히는 경우에는 prompt를 적절하게 넣어서 ChatGPT나 github 혹은 stackoverflow를 참고했다 (역시 인터넷은 스승이다). 별도로 패키지를 import는 하지 않았다. 지금까지의 공부의 중요한 점은
'내가 만든 서비스와 남이 만든 패키지를 비교해보고 내 실력이 무엇이 부족한지 확인하고 더 개선할 방법을 찾는것'
이기 때문에 굳이 패키지를 가져와서 쓰는것은 이번 프로젝트에서는 지양하려고 한다. 물론 필수적인 provider나 http등과 같은 것들은 당연히 쓰겠지만 말이다.
전체 코드는 다음과 같다.
일단 뭐 앱 이름은 birthdayApp이라고 했지만 나중에 바꿀 예정이다.
import 'package:flutter/material.dart';
void main() {
runApp(
MyApp(),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: BirthdayApp(),
);
}
}
class BirthdayApp extends StatefulWidget {
@override
State<BirthdayApp> createState() => _BirthdayAppState();
}
class _BirthdayAppState extends State<BirthdayApp> {
final TextEditingController _dayController = TextEditingController();
String _resultText100 = '';
String _resultText200 = '';
String _resultText300 = '';
String _resultText365 = '';
void calculateResult() {
setState(() {
try {
final enteredDate = DateTime.parse(_dayController.text);
final calculatedDate100 =
enteredDate.add(const Duration(days: 100)).toLocal();
final calculatedDate200 =
enteredDate.add(const Duration(days: 200)).toLocal();
final calculatedDate300 =
enteredDate.add(const Duration(days: 300)).toLocal();
final calculatedDate365 =
enteredDate.add(const Duration(days: 365)).toLocal();
_resultText100 = '100 days: $calculatedDate100';
_resultText200 = '200 days: $calculatedDate200';
_resultText300 = '300 days: $calculatedDate300';
_resultText365 = '1 year: $calculatedDate365';
} catch (e) {
_resultText100 = 'Invalid date format';
_resultText200 = 'Invalid date format';
_resultText300 = 'Invalid date format';
_resultText365 = 'Invalid date format';
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Day Calculator'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Today is'),
Text(
DateTime.now().toLocal().toString(),
style: TextStyle(fontSize: 20),
),
TextField(
decoration: const InputDecoration(
labelText: 'Enter the day',
hintText: 'yyyy-mm-dd',
),
controller: _dayController,
),
SizedBox(
height: 30,
),
ElevatedButton(
onPressed: calculateResult,
child: Text('Calculate'),
),
SizedBox(
height: 30,
),
Text(
_resultText100,
style: TextStyle(fontSize: 20),
),
Text(
_resultText200,
style: TextStyle(fontSize: 20),
),
Text(
_resultText300,
style: TextStyle(fontSize: 20),
),
Text(
_resultText365,
style: TextStyle(fontSize: 20),
),
],
),
),
);
}
}
이번 스켈레톤 구축 과정에서 가장 중요한건 아무래도 string으로 내가 입력 혹은 반환할 값이 무엇인지 확인을 하고 이를 계산할 수 있는 수식을 넣는 것일 거다.
그 부분인 이 클래스를 통해 처리를 했다.
- 언어 입력부분은 TextEditingController()
- String으로 각 '기념일별' 선언 및 초기화
- try... catch 구분으로 각 기념일별 계산 수식 및 return 값을 입력
class BirthdayApp extends StatefulWidget {
@override
State<BirthdayApp> createState() => _BirthdayAppState();
}
(...)
class _BirthdayAppState extends State<BirthdayApp> {
final TextEditingController _dayController = TextEditingController();
String _resultText100 = '';
String _resultText200 = '';
String _resultText300 = '';
String _resultText365 = '';
void calculateResult() {
setState(() {
try {
final enteredDate = DateTime.parse(_dayController.text);
final calculatedDate100 =
enteredDate.add(const Duration(days: 100)).toLocal();
final calculatedDate200 =
enteredDate.add(const Duration(days: 200)).toLocal();
final calculatedDate300 =
enteredDate.add(const Duration(days: 300)).toLocal();
final calculatedDate365 =
enteredDate.add(const Duration(days: 365)).toLocal();
_resultText100 = '100 days: $calculatedDate100';
_resultText200 = '200 days: $calculatedDate200';
_resultText300 = '300 days: $calculatedDate300';
_resultText365 = '1 year: $calculatedDate365';
} catch (e) {
_resultText100 = 'Invalid date format';
_resultText200 = 'Invalid date format';
_resultText300 = 'Invalid date format';
_resultText365 = 'Invalid date format';
}
});
}
(...)
그리고 간단한 UI 반환 부분은 다음과 같다. 가장 중요한 부분만 보여주자면 다음과 같다.
- 현재 날짜를 font 20으로 표시
- Textfield에서는 yyyy-mm-dd로 작성하기를 요청하는 hint Text 참조
- 날짜 계산을 위한 elevatedbutton 생성
- 계산 후 return 값
(...)
Text(
DateTime.now().toLocal().toString(),
style: TextStyle(fontSize: 20),
),
TextField(
decoration: const InputDecoration(
labelText: 'Enter the day',
hintText: 'yyyy-mm-dd',
),
controller: _dayController,
),
SizedBox(
height: 30,
),
ElevatedButton(
onPressed: calculateResult,
child: Text('Calculate'),
),
SizedBox(
height: 30,
),
Text(
_resultText100,
style: TextStyle(fontSize: 20),
),
Text(
_resultText200,
style: TextStyle(fontSize: 20),
),
Text(
_resultText300,
style: TextStyle(fontSize: 20),
),
Text(
_resultText365,
style: TextStyle(fontSize: 20),
),
(...)
이 정도는 아마 기초과정을 마친 분들은 대부분 마치지 않을까? 중요한것은 이걸 혼자서 생각하고 짜나갈 수 있냐는 거니까.
자 다음은 앞에서 말한 부분을 조금 더 발전 시켜보자.
- 날짜 표현을 '간결하게' 표시하기
- '아이콘'등을 추가하기
- '사이드바'를 추가하여 메모 남기기
- 전체적인 UI 수정하기
'Flutter' 카테고리의 다른 글
[Project] '만난지 며칠' 날짜 앱 만들기 - Chp 3. 메인화면 구성 (0) | 2023.05.24 |
---|---|
[Flutter] Refactoring (리팩토링) - Extract Method, Extract Widget (0) | 2023.05.22 |
[Project] '만난지 며칠' 날짜 앱 만들기 - Chp 1. 구상 (0) | 2023.05.17 |
[이론] MQTT란 무엇인가? (0) | 2023.05.15 |
[Firebase+provider]Chp5. Chat App 채팅 기능 구현하기 II (1) | 2023.05.14 |