Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- CKA 기출문제
- kotlin spring
- aws
- minikube
- 기록으로 실력을 쌓자
- AI
- kotlin coroutine
- 정보처리기사 실기
- 티스토리챌린지
- 오블완
- APM
- Java
- Pinpoint
- 정보처리기사실기 기출문제
- mysql 튜닝
- PETERICA
- 정보처리기사 실기 기출문제
- CloudWatch
- kotlin querydsl
- Kubernetes
- AWS EKS
- Elasticsearch
- Spring
- kotlin
- CKA
- 코틀린 코루틴의 정석
- IntelliJ
- MySQL
- Linux
- 공부
Archives
- Today
- Total
피터의 개발이야기
[flutter] 일정 관리 앱 - 달력 및 입력 폼 작성 본문
반응형
ㅁ 들어가며
ㅇ 코드팩토리의 플러터 프로그래밍 책을 보며 실습 중 일정 관리 앱을 개발하는 과정을 정리하였다.
ㅁ calendar_scheduler 프로젝트 생성
ㅇ pubspec.yaml 수정
...........
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2 # iOS style 날짜 토굴
table_calendar: 3.0.7 # 달력
intl: 0.17.0 # 다국어
drift: 2.1.0 # Drift
sqlite3_flutter_libs: 0.5.10 # SQLite
path_provider: 2.0.11 # 경로기능
path: 1.8.3 # 경로기능
get_it: 7.2.0 # 프로젝트 전역으로 의존성 주입
dio: 4.0.6 # 네트워크 요청
provider: 6.0.3 # 상태 관리를 가능
uuid: 3.0.6 # UUID 생성용
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
drift_dev: ^2.1.0 #// Drift 코드 생성 기능 관련 플러그인
build_runner: ^2.2.0 #// 코드 생성 기능을 제공해주는 플러그인
ㅁ Table Calendar 사용법
import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';
// Table Calendar 사용법
void main() {
runApp(
MaterialApp(
home: Scaffold(
// Calendar 위젯
body: TableCalendar(
// min Date
firstDay: DateTime(2000,1,1),
// max Date
lastDay: DateTime(2025,12,31),
// 표시되는 날짜
focusedDay: DateTime.now(),
// 선택한 날짜를 인식하는 함수
selectedDayPredicate: (DateTime day){
final now = DateTime.now();
return DateTime(day.year, day.month, day.day).isAtSameMomentAs(
DateTime(now.year,now.month,now.day),
);
},
// 날짜 선택 시
onDaySelected: (DateTime selectedDay, DateTime focusedDay){
print('onDaySelected');
},
// 날짜 변경 시
onPageChanged: (DateTime focusedDay){
print('onPageChanged');
},
// 기간 선택 모드
rangeSelectionMode: RangeSelectionMode.toggledOn,
// 기간 선탠 시
onRangeSelected: (DateTime? start, DateTime? end, DateTime focusedDay){
print('rangeSelectionMode');
},
),
),
)
);
}
ㅁ 프로젝트 초기화
ㅁ 16장 일정 관리 앱 만들기 - 달력 구현하기, 주색상 설정
ㅇ colors.dart
import 'package:flutter/material.dart';
// 주색상 설정
const PRIMARY_COLOR = Color(0xFF0DB2B2);
final LIGHT_GREY_COLOR = Colors.grey[200]!;
final DARK_GREY_COLOR = Colors.grey[600]!;
final TEXT_FIELD_FILL_COLOR = Colors.grey[300]!;
ㅁ 16장 일정 관리 앱 만들기 - 달력 구현하기 - 날짜 선택 기능
ㅇ stateful으로 변경 및 선택 날짜 변수와 날짜 선택 시 실행함 수 주입
ㅇ 날짜의 디자인 적용 및 날짜 선택 시 기능 구현
ㅁ 16장 일정 관리 앱 만들기 - 달력 구현하기 - 선택 날짜 일정보여주기
import 'package:calendar_scheduler/const/colors.dart';
import 'package:flutter/material.dart';
class ScheduleCard extends StatelessWidget {
final int startTime;
final int endTime;
final String content;
const ScheduleCard({
required this.startTime,
required this.endTime,
required this.content,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
border: Border.all(
width: 1.0,
color: PRIMARY_COLOR,
),
borderRadius: BorderRadius.circular(8.0),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: IntrinsicHeight( // 높이를 내부 위젯들의 최대 높이로 설정
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// 시간 위젯
_Time(
startTime: startTime,
endTime: endTime,
),
SizedBox(width: 16.0),
// 일정 내용 위젯
_Content(
content: content,
),
SizedBox(width: 16.0),
],
),
),
),
);
}
}
///////////////
// 자식 위젯들 생성
// 시간을 표시할 위젯 생성
class _Time extends StatelessWidget {
final int startTime; // 시작 시간
final int endTime; // 종료 시간
const _Time({
required this.startTime,
required this.endTime,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final textStyle = TextStyle(
fontWeight: FontWeight.w600,
color: PRIMARY_COLOR,
fontSize: 16.0,
);
return Column( // 일정을 세로로 배치
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
// 숫자가 한 자리면 0으로 채워기
'${startTime.toString().padLeft(2, '0')}:00',
style: textStyle,
),
Text(
'${endTime.toString().padLeft(2, '0')}:00', // 숫자가 두 자리수가 안 되면 0으로 채워주기
style: textStyle.copyWith(
fontSize: 10.0,
),
),
],
);
}
}
// 내용을 표시할 위젯
class _Content extends StatelessWidget {
final String content; // 내용
const _Content({
required this.content,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Expanded( // 최대한 넓게 늘리기
child: Text(
content,
),
);
}
}
ㅇ schedule_card.dart
ㅇ 시간과 일정 위젯을 만들고 이것을 Row로 묶어 스케줄카드 위젯으로 묶음.
ㅇ 메인 달력 밑에 일정카드 생성하여 보여줌.
ㅁ 16장 일정 관리 앱 만들기 - 선택 일정 갯수 표시 배너 추가
import 'package:calendar_scheduler/const/colors.dart';
import 'package:flutter/material.dart';
class TodayBanner extends StatelessWidget {
final DateTime selectedDate; // 선택된 날짜
final int count; // 일정 개수
const TodayBanner({
required this.selectedDate,
required this.count,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
// 기본 글꼴
final textStyle = TextStyle(
fontWeight: FontWeight.w600,
color: Colors.white,
);
return Container(
color: PRIMARY_COLOR,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Row(
// 양 끝으로 배치
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// 일정
Text(
'${selectedDate.year}.${selectedDate.month}.${selectedDate.day}',
style: textStyle,
),
// 일정 개수 표시
Text(
'$count개',
style: textStyle,
),
],
),
),
);
}
}
ㅇ today_banner.dart 생성
ㅇ 날짜와 갯수를 보여주는 row 생성.
ㅇ 생성된 banner를 달력 밑에 배열시킴.
ㅁ 16장 일정 관리 앱 만들기 - 일정 입력 폼 만들기
import 'package:flutter/material.dart';
import 'package:calendar_scheduler/component/custom_text_field.dart';
import 'package:calendar_scheduler/const/colors.dart';
class ScheduleBottomSheet extends StatefulWidget {
const ScheduleBottomSheet({Key? key}) : super(key: key);
@override
State<ScheduleBottomSheet> createState() => _ScheduleBottomSheetState();
}
class _ScheduleBottomSheetState extends State<ScheduleBottomSheet> {
@override
Widget build(BuildContext context) {
final bottomInset = MediaQuery.of(context).viewInsets.bottom;
return SafeArea(
child: Container(
// 화면 반 높이에 키보드 높이 추가하기
height: MediaQuery.of(context).size.height / 2 + bottomInset,
color: Colors.white,
child: Padding(
padding: EdgeInsets.only(
left: 8,
right: 8,
top: 8,
bottom: bottomInset
),
child: Column(
// ➋ 시간 관련 텍스트 필드와 내용관련 텍스트 필드 세로로 배치
children: [
Row(
// ➊ 시작 시간 종료 시간 가로로 배치
children: [
Expanded(
child: CustomTextField(
// 시작시간 입력 필드
label: '시작 시간',
isTime: true,
),
),
const SizedBox(width: 16.0),
Expanded(
child: CustomTextField(
// 종료시간 입력 필드
label: '종료 시간',
isTime: true,
),
),
],
),
SizedBox(height: 8.0),
Expanded(
child: CustomTextField(
// 내용 입력 필드
label: '내용',
isTime: false,
),
),
SizedBox(
width: double.infinity,
child: ElevatedButton(
// [저장] 버튼
onPressed: onSavePressed,
style: ElevatedButton.styleFrom(
primary: PRIMARY_COLOR,
),
child: Text('저장하기'),
),
),
],
),
),
),
);
}
void onSavePressed() {
print('저장버튼 클릭!!');
}
}
ㅇ schedule_bottom_sheet.dart 생성
ㅇ 시작과 종료 시간, 내용 필드의 배치
import 'package:calendar_scheduler/const/colors.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class CustomTextField extends StatelessWidget {
final String label;
final bool isTime; // 시간 선택하는 텍스트 필드인지 여부
const CustomTextField({
required this.label,
required this.isTime,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column( // 세로로 텍스트와 텍스트 필드를 위치
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
label,
style: TextStyle(
color: PRIMARY_COLOR,
fontWeight: FontWeight.w600,
),
),
Expanded(
flex: isTime ? 0 : 1,
child: TextFormField(
cursorColor: Colors.grey, // 커서 색상 변경
maxLines: isTime ? 1 : null, // 시간 관련 텍스트 필드가 아니면 한 줄이상 작성 가능
expands: !isTime, // 시간 관련 텍스트 필드는 공간 최대 차지
keyboardType: isTime ? TextInputType.number : TextInputType.multiline, // ➌ 시간 관련 텍스트 필드는 기본 숫자 키보드 아니면 일반 글자 키보드 보여주기
// 시간은 숫자로만 입력제한
inputFormatters: isTime?
[
FilteringTextInputFormatter.digitsOnly,
] :
[],
decoration: InputDecoration(
// 테두리 삭제
border: InputBorder.none,
// 배경색을 지정
filled: true,
fillColor: Colors.grey[300], // 배경색
suffixText: isTime ? '시' : null, // 시간 관련 텍스트 필드는 ‘시' 접미사 추가
),
),
),
],
);
}
}
ㅇ custom_text_field.dart
ㅇ 입력 필드들의 디자인 패턴 주입 및 시간은 숫자만 입력 제한
ㅇ 메인 화면에 추가 버튼 클릭 시 스케줄 입력 폼이 생성됨.
ㅇ 키보드가 팝업될 경우 입력 폼 가림 현상 해결.
ㅁ 16장 일정 관리 앱 만들기 - 날짜 한국어 지원
ㅁ 함께 보면 좋은 사이트
ㅇ flutter cookbook - Build a Flutter layout
ㄴ 플루터 쿡북 중 레이아웃 페이지 링크
ㅇ codelabs- 첫 번째 Flutter 앱
ㄴ 환경을 잡고 테스트를 해보기 좋은 튜토리얼
반응형
'Programming > Flutter' 카테고리의 다른 글
[flutter] 일정 관리 앱 - 로컬 데이터 저장 SQLite, 드리프트 플러그인 (0) | 2024.02.21 |
---|---|
[flutter] Cupertino DatePicker 설정, min max date 지정 (0) | 2024.02.20 |
[flutter] DateFormat 한글 설정 (0) | 2024.02.20 |
[flutter] 만난 지 며칠 U&I, Cupertino DatePicker 설정 (1) | 2024.02.20 |
[flutter] 전자액자 만들기 (2) | 2024.02.19 |
Comments