-
[개발일지] flutter 앱개발 3주차Study/Development 2022. 9. 23. 16:57
<스파르타코딩 flutter 강의 수강일지>
3주차: 패키지 사용법 익히기 & 앱 기능 만들기
1. Flutter 패키지 관련 사이트
Pub.dev
플러터 패키지를 모아둔 사이트
Dart packages
Pub is the package manager for the Dart programming language, containing reusable libraries & packages for Flutter, AngularDart, and general Dart programs.
pub.dev
Awsome Flutter
Flutter에 관련된 모든 자료를 모아둔 Github 문서
https://github.com/Solido/awesome-flutter#ui
GitHub - Solido/awesome-flutter: An awesome list that curates the best Flutter libraries, tools, tutorials, articles and more.
An awesome list that curates the best Flutter libraries, tools, tutorials, articles and more. - GitHub - Solido/awesome-flutter: An awesome list that curates the best Flutter libraries, tools, tuto...
github.com
Flutter Gems
카테고리별 플러터 패키지 추천
Flutter Gems - A Curated List of Dart & Flutter packages
Flutter Gems is a curated list of Dart & Flutter packages that are categorized based on functionality. Flutter Gems is also a visual alternative to pub.dev
fluttergems.dev
2. 패키지 설치하는 법(Terminal)
flutter pub add <설치하려는 패키지 이름>
*설치해본 패키지들
- introduction_screen : 온보딩 화면 패키지
- google_fonts : 폰트 패키지
- table_calendar : 달력 위젯
- provider : 상태 관리
- intl : DateTime 형식 지정
- shared_preferences : 데이터 저장
3. Onboarding Page
3페이지짜리 온보딩 페이지 기본 뼈대
body: IntroductionScreen( pages: [ // 페이지1 PageViewModel( title: "Title1", bodyWidget: Text("body1"), ), // 페이지2 PageViewModel( title: "Title2", bodyWidget: Text("body2"), ), ], next: Text("Next", style: TextStyle(fontWeight: FontWeight.w600)), done: Text("Done", style: TextStyle(fontWeight: FontWeight.w600)), onDone: () { // When done button is press }, ),
4. 기본 데이터 처리 기능 CRUD
- Create
- Read
- Update
- Delete
Provider Package 이용한 CRUD 샘플
/// Diary 목록 List<Diary> diaryList = []; /// 특정 날짜의 diary 조회 List<Diary> getByDate(DateTime date) { return diaryList .where((diary) => isSameDay(date, diary.createdAt)) .toList(); } /// Diary 작성 void create(String text, DateTime selectedDate) { DateTime now = DateTime.now(); DateTime createdAt = DateTime( selectedDate.year, selectedDate.month, selectedDate.day, now.hour, now.minute, now.second, ); Diary diary = Diary( text: text, createdAt: createdAt, ); diaryList.add(diary); notifyListeners(); } /// Diary 수정 void update(DateTime createdAt, String newContent) { Diary diary = diaryList.firstWhere(((diary) => diary.createdAt == createdAt)); diary.text = newContent; notifyListeners(); } /// Diary 삭제 void delete(DateTime createdAt) { diaryList.removeWhere((diary) => diary.createdAt == createdAt); notifyListeners(); }
5. SharedPreferences에 커스텀 클래스를 저장
커스텀 클래스 → Map → jsonString → Map → 커스텀 클래스 변환
import 'dart:convert'; void main() { Diary diary = Diary("오늘 일기", DateTime.now()); // 1) Diary ➡ Map Map<String, dynamic> map = diary.toJson(); print("1) Diary ➡ Map : $map"); // 2) Map ➡ jsonString String jsonString = jsonEncode(map); print("2) Map ➡ jsonString : $jsonString"); // 3) jsonString ➡ Map Map<String, dynamic> jsonMap = jsonDecode(jsonString); print("3) jsonString ➡ Map : $jsonMap"); // 4) Map ➡ Diary Diary parsedDiary = Diary.fromJson(jsonMap); print("4) Map ➡ Diary : $parsedDiary"); } class Diary{ String text; DateTime createdAt; Diary(this.text, this.createdAt); // Diary -> Map Map<String, dynamic> toJson() { return { "text": text, "createdAt": createdAt.toString(), }; } // Map -> Diary factory Diary.fromJson(Map<String, dynamic> json) { return Diary( json["text"], DateTime.parse(json["createdAt"]), ); } }
실습과제에 사용한 코드
void main() async { // 메인 함수에 추가하여야 할 코드 WidgetsFlutterBinding.ensureInitialized(); SharedPreferences prefs = await SharedPreferences.getInstance(); runApp( MultiProvider( providers: [ ChangeNotifierProvider(create: (context) => DiaryService(prefs)), ], child: const MyApp(), ), ); }
import 'dart:convert'; import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:table_calendar/table_calendar.dart'; class Diary { String text; // 내용 DateTime createdAt; // 작성 시간 Diary({ required this.text, required this.createdAt, }); Map<String, dynamic> toJson() { return {"text": text, "createdAt": createdAt.toString()}; } factory Diary.fromJson(Map<String, dynamic> jsonMap) { return Diary( text: jsonMap['text'], createdAt: DateTime.parse(jsonMap['createdAt'])); } } class DiaryService extends ChangeNotifier { SharedPreferences prefs; DiaryService(this.prefs) { List<String> stringDiaryList = prefs.getStringList('diaryList') ?? []; for (String stringDiary in stringDiaryList) { // stringDiary ==> Diary Map<String, dynamic> jsonMap = jsonDecode(stringDiary); Diary diary = Diary.fromJson(jsonMap); diaryList.add(diary); } } /// Diary 목록 List<Diary> diaryList = []; /// 특정 날짜의 diary 조회 List<Diary> getByDate(DateTime date) { return diaryList .where((diary) => isSameDay(date, diary.createdAt)) .toList(); } /// Diary 작성 void create(String text, DateTime selectedDate) { DateTime now = DateTime.now(); DateTime createdAt = DateTime( selectedDate.year, selectedDate.month, selectedDate.day, now.hour, now.minute, now.second, ); Diary diary = Diary( text: text, createdAt: createdAt, ); diaryList.add(diary); print(inspect(diary)); notifyListeners(); _saveDiaryList(); } /// Diary 수정 void update(DateTime createdAt, String newContent) { Diary diary = diaryList.firstWhere(((diary) => diary.createdAt == createdAt)); diary.text = newContent; notifyListeners(); _saveDiaryList(); } /// Diary 삭제 void delete(DateTime createdAt) { diaryList.removeWhere((diary) => diary.createdAt == createdAt); notifyListeners(); _saveDiaryList(); } /// Diary prefs 저장 void _saveDiaryList() { List<String> stringDiaryList = []; for (Diary diary in diaryList) { Map<String, dynamic> jsonMap = diary.toJson(); String stringDiary = jsonEncode(jsonMap); stringDiaryList.add(stringDiary); } prefs.setStringList('diaryList', stringDiaryList); } }
알아둬야 할 것들
1. Where() 메소드
where()
배열 요소를 필터링한다.
final numbers = <int>[1, 2, 3, 5, 6, 7]; // 5보다 작은 요소 반환 var result = numbers.where((x) => x < 5); // (1, 2, 3) // 5보다 큰 요소 반환 result = numbers.where((x) => x > 5); // (6, 7) // 짝수 반환 result = numbers.where((x) => x.isEven); // (2, 6)
firstWhere()
요소를 반복하고 주어진 조건의 첫번째 요소를 반환한다.
*lastWhere(): 마지막 요소 반환
// 6으로 나눴을 때, 나머지가 0인 것 반환 var result = await Stream.fromIterable([1, 3, 4, 9, 12]) .firstWhere((element) => element % 6 == 0, orElse: () => -1); print(result); // 12 // 찾고자 하는 값이 없을 때 result = await Stream.fromIterable([1, 2, 3, 4, 5]) .firstWhere((element) => element % 6 == 0, orElse: () => -1); print(result); // -1
removeWhere()
주어진 조건에 맞는 모든 요소를 제거
final numbers = <String>['one', 'two', 'three', 'four']; // 글자수가 3인 요소 제거 numbers.removeWhere((item) => item.length == 3); print(numbers); // [three, four]
2. Null Safety
e1! // e1이 null 인 경우 에러 발생 e2 ?? e3 // e2가 null 일 경우 e3을 사용 x ??= e4 // x가 null 일 경우 `x = e4`. e5?.foo() // e5가 null이 아니면, e5에 `foo`함수 실행 [...? e6] // e6이 null이 아니면, e6을 list로 spread하여 확장
오류 탐험
DateTime을 받아올 때, 순서를 잘못넣어서 오류가 생겼다.
day 데이터가 year자리에 들어간 것 때문에, 계속 화면에 나타나지 않았었다.
순서에 유의하도록 해야겠다.
커스텀 클래스의 인스턴스 내용을 살펴 볼 때 inspect()를 사용한다.
print(inspect(diary));
반응형'Study > Development' 카테고리의 다른 글
[개발일지] flutter 앱개발 5주차 (0) 2022.10.03 [개발일지] flutter 앱개발 4주차 (0) 2022.10.02 [개발일지] flutter 앱개발 2주차 (0) 2022.09.12 [개발일지] flutter 앱개발 1주차 (0) 2022.08.30 [개발일지] Dart 입문 4: Asynchronous Programming (0) 2022.08.21