다른 사람들이 만들어 둔 위젯을 활용하는 것이 패키지.
클럽하우스 = 아고라라는 음성통화 패키지를 이용한 개발 > 개발 기한 단축
실제로 남이 패키지로 짜둔 코딩이 왕초보 코더가 짠 것보다 깔끔하고 효율적일 가능성이 높음.
https://pub.dev/
Flutter Favorite에 있는 기능을 활용하면 도움이 될 수 있음.
(1.XXX 버전으로 가야 정식 버전인 것임.
0.XXX는 베타/테스트 버전)
https://github.com/Solido/awesome-flutter#ui
Github에 모아둔 Flutter 패키지 모음.
https://fluttergems.dev/
페이지를 열었을 때 가장 먼저 뜨는 소개화면(튜토리얼 화면) 만드는 방법.
introduction_screen페이지를 제작한다.
https://pub.dev/packages/introduction_screen
설치하는 방식은 2가지 (installing 페이지 잘 읽어보면 되고, Sample코드만 잘 쓸줄 알면 됨)
// Done 클릭시 페이지 이동 (Done을 클릭하는 이유는 튜토리얼 끝나고 정식 어플 화면으로 넘어가야하기 때문)
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
Navigator.push를 Navigator.pushReplacement로 변경하면 다시는 Done페이지로 안 돌아갑니다.
(뒤로가기 버튼 사라짐 / 페이지도 스택으로 안 쌓임)
- Create / Read / Update / Delete 기능 구현하기
google_fonts 패키지를 이용하기
https://pub.dev/packages/google_fonts/install
https://fonts.google.com/?subset=korean
구글 폰트 설정이 들어가는 코드.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
textTheme: GoogleFonts.getTextTheme('Jua'),
),
home: OnboardingPage(),
);
}
}
textTheme: 전체 어플의 폰트를 바꿔주는 코드.
어플을 켤때마다 온보딩(튜토리얼 페이지)가 매번 뜬다면? 굉장히 불편.
이것을 체크하는 페이지가 shared_preferences라는 패키지. (로컬에 온보딩 여부를 저장하는 것. local Setting (스마트폰에 저장하는 것임)
1. 파일로 저장하기
2. DB에 저장하기
3. 클라우드 서버에 저장하기.
https://pub.dev/packages/shared_preferences/install
주의사항
1. Key Value가 있는 Map타입의 데이터이다.
late SharedPreferences prefs;
late : 전역변수에서 값을 설정해야 하는 에러가 발생할 때 쓰면 됨.
(지역변수 설정할 때, 그 앞에 전역변수 설정시 이니셜라이즈 안되었을 때 생기는 오류 방지)
버킷리스트 앱 만들기
1. 버킷 리스트 작성(Create)
2. 버킷 리스트 조회(Read)
3. 버킷 리스트 수정(Update)
4. 버킷 리스트 삭제(Delete)
입력된 값에 접근하기 위한 요소
// TextField의 값을 가져올 때 사용합니다.
class _CreatePageState extends State<CreatePage> {
// TextField의 값을 가져올 때 사용합니다.
TextEditingController textController = TextEditingController();
TextField(
controller: textController, // 연결해 줍니다.
autofocus: true,
decoration: InputDecoration(
hintText: "하고 싶은 일을 입력하세요",
),
onPressed: () {
// 추가하기 버튼 클릭시
String job = textController.text; // 값 가져오기 <1>
Navigator.pop(context, job); // job 변수를 반환하며 화면을 종료합니다. <2>
class _HomePageState extends State<HomePage> {
List<String> bucketList = ['여행가기', '앱만들기']; // 전체 버킷리스트 목록
onPressed: () async {
// + 버튼 클릭시 버킷 생성 페이지로 이동
String? job = await Navigator.push( //job변수는 위에서 받아온 job임. <3>
context,
MaterialPageRoute(builder: (_) => CreatePage()),
);
if (job != null) {
setState(() {
bucketList.add(job); // 버킷 리스트에 추가 <4>
});
}
},
함수가 async가 되어야지 await를 사용할 수 있음
버킷리스트에서 업데이트가 되는 부분.
onTap: () {
setState(() {
bucket.isDone = !bucket.isDone;
});
},
color: bucket.isDone ? Colors.grey : Colors.black,
decoration: bucket.isDone
? TextDecoration.lineThrough
: TextDecoration.none,
),
버킷리스트에서 삭제가 되는 부분
void ShowDeleteDialog(BuildContext context, int index) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("정말로 삭제하시겠습니까?"),
actions: [
// 취소 버튼
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("취소"),
),
// 확인 버튼
TextButton(
onPressed: () {
Navigator.pop(context);
setState(() {
// index에 해당하는 항목 삭제
bucketList.removeAt(index);
});
},
child: Text(
"확인",
style: TextStyle(color: Colors.pink),
),
),
],
);
},
);
}
}
각기 다른 페이지에서 인자를 주고받는게 실제로 선언을 해주려면 불편할 수 있음.
이를 방지하기 위해서 필요한 것이 <상태관리>
하나의 풀속에 모든 변수를 몰아넣고, 나머지 페이지에서 데이터를 관리하는 방식을 취하자.
그 역할을 해주는 것이 BucketService
ChangeNotifier : 화면에서 무언가 변경이 있을 때, 변경을 감지하는 요소.
버킷리스트에서 Consumer 위젯을 쓰는 이유.
Consumer<BucketService>(builder: (context) 이런식으로 되어있으면 에러가 뜸.
왜냐하면 Builder가 받는 인자가 context가 아니라 3가지 context, bucketService, child 를 받기 때문에.
Widget build(BuildContext context) {
return Consumer<BucketService>(
builder: (context, bucketService, child) {
// bucketService로 부터 bucketList 가져오기
List<Bucket> bucketList = bucketService.bucketList;
동작 방식 : Consumer를 통해서 bucketService에 접근을 할 수 있도록 해주고, 따로 만들어둔 BucketService에 접근할 수 있도록 Provider를 미리등록해주었음.
providers: [
ChangeNotifierProvider(create: (context) => BucketService()),
]
BucketService을 가져오기 위해선 Consumer로 Scaffold를 감싸주어야 동작을 함.
BucketService를 가져오고 나면 bucketService 라는 변수에 값을 넣어주는 것
// BucketService 가져오기
BucketService bucketService = context.read<BucketService>();
bucketService.createBucket(job);
Navigator.pop(context); // 화면을 종료합니다
Provider는 사용법이 어려우니 반복해서 학습할 것!
3주차 과제
선택한 날짜에 일기 작성하기
날짜 선택하면 해당 날짜의 일기 보여주기
일기를 클릭하여 수정하기
일기를 길게 클릭하여 삭제하기
사용한 패키지 목록.
Table_calendar : 달력 위젯
provider : 상태관리
intl : DateTime 형식 지정
shared_perferences : 데이터 저장
SharedPerferences 패키지로 어플을 꺼도 저장되도록 만들기.
Diary > String = JSON을 이용하면 편하다.
jsonEncode : Dart > JSON으로 변환
jsonDecode : JSON > Dart자료형으로 변환