https://www.youtube.com/watch?v=mOtWvKkvC7A
description: |-
1. 이건 꼭 알아야 한다[^1]
[? 질문] 모바일 앱(안드로이드/iOS)을 만드는 대표적인 방식들은 무엇이며, 각 방식의 장단점은 무엇인가[^12]
[= 답] 네이티브/웹뷰 기반 웹/하이브리드/크로스플랫폼으로 나뉘며, 성능·사용자경험·개발비용·플랫폼 호환성 관점에서 트레이드오프가 존재한다(네이티브는 최고 성능이지만 코드베이스 2개, 웹은 배포가 빠르지만 “웹같이” 보임, 하이브리드는 깜빡임은 줄지만 웹뷰 한계, 크로스플랫폼은 코드 1개로 양 플랫폼 대응).[^13][^18][^24]
[? 질문] Flutter로 앱을 개발하려면 무엇을 설치·설정해야 하고, “프로젝트 생성→실행”까지 최소 흐름은 어떻게 되는가[^26]
[= 답] Android Studio 설치 → Flutter SDK 설치(Windows는 환경변수 PATH에 flutter/bin 추가) → Android Studio에 Flutter 플러그인 설치 → Flutter 프로젝트 생성(패키지명/조직명 포함) → 에뮬레이터(AVD) 또는 실기기 연결 후 Run으로 실행, Hot Reload로 UI 변경을 즉시 확인한다.[^35][^54][^86]
[? 질문] Flutter/다트(Dart) 초심자가 반드시 익혀야 하는 언어 핵심 5요소는 무엇이고, 왜 중요한가[^93]
[= 답] 데이터(단일/복수), 함수(재사용·매개변수·리턴), 조건문, 반복문, 클래스(규격화된 복합 데이터 타입/객체 지향의 기반)이며, 이 5가지로 프론트·백엔드·앱 개발 전반의 로직을 대부분 구성할 수 있다.[^95][^125]
[? 질문] Flutter에서 “데이터가 바뀌면 화면(UI)이 자동으로 바뀌지 않는 이유”와, UI를 갱신하는 방법은 무엇인가[^220]
[= 답] 단순히 변수 값만 변경해도 UI가 다시 그려지지 않기 때문에, 상태(State)가 바뀌었음을 프레임워크에 알리고 “다시 빌드(리빌드)”하도록 해야 한다. StatefulWidget에서는 setState()로 상태 변경+리빌드를 트리거한다.[^221][^228]
[? 질문] 앱이 서버(REST API)에 요청해 JSON을 받아 화면에 보여주려면, 어떤 개념·도구·코드 구조가 필요한가[^248]
[= 답] REST API(URL로 데이터 송수신) 이해 → http 패키지 추가(pub.dev) → 비동기(Future/async/await)로 GET 요청 → 응답 body(JSON 문자열)를 jsonDecode로 Map/List로 변환 → setState로 UI에 반영 → 필드가 많아지면 모델(VO) 클래스로 매핑(fromJson)해 UI코드와 데이터 로직을 정리한다.[^253][^285][^312]
2. 큰 그림[^6]
이 강의는 Flutter를 처음 접하는 학습자를 대상으로, 앱 개발 방식의 전체 지형을 정리한 뒤 Flutter 개발환경을 설치·실행하고, Dart 언어 핵심 문법을 실습으로 익힌 다음, 위젯(UI) 구성과 상태 변경(setState), REST API 통신 및 JSON→모델 변환까지 “앱이 동작하는 최소 단위”를 직접 구현하는 흐름으로 구성된다.[^12][^86][^228]
- Flutter는 크로스플랫폼으로, 하나의 코드베이스로 안드로이드/iOS를 동시에 개발·배포하는 것을 목표로 하며, 플랫폼 위에 “새로 그려나가는 방식” 비유로 호환성/일관된 UI를 설명한다.[^24][^26]
- Flutter의 UI는 전부 위젯(Widget) 이며, 위젯 트리/속성(key-value) 조합으로 화면을 구성한다(Scaffold, Container, Column/Row, Text, Image, Button 등).[^7][^185]
- 앱은 결국 서버·DB와 연결되어야 하므로 REST API + HTTP 요청 + JSON 파싱 + 상태 반영이 중요하고, 규모가 커지면 모델(VO) 클래스로 데이터 구조를 규격화해 유지보수성을 높인다.[^248][^302]
3. 하나씩 살펴보기[^1]
3.1 강사 소개, 수업 자료/진행 방식[^2]
강사는 KISA(키사)에서 진행하는 웹테크 밋업에서 Flutter 강의를 맡은 홍정민이며, (주)올리고컴퍼니 기술이사로 개발 총괄을 맡고 있다고 소개한다.[^2][^3] 또한 한국 기술사업화 진흥협회 대구지사에서 K-디지털 강의들을 진행해왔고, 현업에서 쓰는 실무 기술을 수업에서 최대한 전달하겠다고 강조한다.[^3][^4]
수업 자료는 제공되는 PDF와 별도의 노션(Notion) 자료를 병행하고, 진행 방식은 “코드 중심”으로 하되 개념 설명은 PDF/노션으로 보완하겠다고 안내한다.[^5][^6] 강의 목차는 모바일 앱 개발 방식 소개 → Dart 언어 기초 → 위젯 → 상태관리 → REST API(HTTP)로 데이터 요청 → Provider와 HTTP 데이터 결합 등으로 잡았지만, 이해를 위해 유동적으로 진행한다고 말한다.[^7][^8]
3.2 모바일 앱 개발 방식 4가지: 네이티브/웹/하이브리드/크로스플랫폼[^12]
강의는 먼저 모바일 OS가 안드로이드(구글)와 iOS(애플) 두 가지이며, 이 플랫폼에서 서비스가 동작하도록 만드는 프로그램이 앱(어플리케이션)이라는 점을 상기시킨다.[^12][^13] 문제는 안드로이드와 iOS는 개발 언어·패턴이 달라 “둘 다 만들려면” 개발 방식 선택이 중요해진다는 맥락을 제시한다.[^14]
3.2.1 네이티브 앱(Native App)[^15]
네이티브 앱은 각 플랫폼의 고유 언어/기술로 개발하는 방식이다.[^15] 예로 안드로이드는 Java/Kotlin, iOS는 Objective-C/Swift 등을 든다.[^15]
- 장점: 최고의 성능, 반응성.[^16]
- 단점: 코드베이스가 2개(플랫폼별 별도 개발)라서 개발 인력/비용이 2배에 가까워질 수 있다.[^16][^17]
- 적합한 경우: 고성능/빠른 수행이 필수인 앱에서 전통적으로 사용해왔으나, 최근 스마트폰 성능이 좋아져 타 방식도 대체로 잘 돌아간다는 뉘앙스를 덧붙인다.[^18]
3.2.2 웹(Web) + 웹뷰(WebView)[^19]
웹은 “모바일 화면에 맞춘 웹사이트”를 만들고, 네이티브 앱의 웹뷰 기능으로 전체 화면에 사이트를 띄우는 방식으로 설명한다.[^19] 즉 URL을 웹뷰에 넣으면 앱처럼 보이지만 본질은 웹사이트라는 것이다.[^19]
- 장점: 배포가 빠르고, 앱을 “딥하게” 공부하지 않아도 웹 개발자도 쉽게 개발 가능.[^20]
- 단점: 사용자도 웹사이트처럼 보인다고 느낄 정도로 UX 차이가 드러날 수 있음(화면 전환 깜빡임, 애니메이션/전환 가속도 등의 차이).[^21]
- 적합한 경우: 빠른 배포, 컨텐츠 중심(뉴스/커머스/포털 등)처럼 내용이 많은 기존 웹서비스를 앱화할 때. 웹을 네이티브로 옮기려면 앱 코드 작업량이 커지기 때문에 웹이 유리하다고 설명한다.[^22]
3.2.3 하이브리드 앱(Hybrid App)[^23]
강사는 “리액트 네이티브나 플러터”를 하이브리드로 오해하는 경우가 있다고 말하면서, 여기서 말하는 하이브리드는 “웹앱의 프런트 코드를 앱 내부에 포함”해 웹뷰에서 실행하는 방식이라고 정의한다.[^23] 브라우저가 서버에서 프런트를 내려받는 웹과 달리, 하이브리드는 프런트 코드가 앱 안에 있어 깜빡임이 줄어든다고 설명한다.[^23]
- 장점: 웹처럼 내려받는 과정이 아니라서 화면 깜빡임이 없음.[^23]
- 단점: 웹뷰 성능의 한계, 복잡한 애니메이션 처리 한계, HTML 기반 UI 구성의 제약 등.[^23]
3.2.4 크로스 플랫폼(Cross Platform): React Native vs Flutter[^24]
2014년 페이스북(현재 메타)이 React/React Native를 발표했고, React Native가 크로스플랫폼의 대표 사례가 되었다고 소개한다.[^24] 크로스플랫폼의 핵심은 “하나의 코드베이스로 iOS/안드로이드 모두 배포”하는 것이다.[^24]
- React Native: 자바스크립트 기반이며, 필요한 네이티브 코드를 꺼내 쓰는 구조로 설명한다.[^24]
- 장점: 코드 1개로 두 OS 대응.[^24]
- 단점(Flutter와 비교 관점): 네이티브 코드를 호출하기 때문에 OS/버전별 분기 처리가 많아질 수 있고, 블루투스/NFC 같은 복잡 기능에서 오픈소스/플러그인 상황에 따라 어려움이 있을 수 있다고 말한다.[^24]
2019년 구글이 Flutter를 발표했고, Flutter도 동일하게 크로스플랫폼이지만 언어는 Dart를 사용한다고 설명한다.[^25] Flutter의 방식 차이는 “운영체제 위에 흰 도화지를 얹어 새로 그려나간다”는 비유로 설명하며, OS와 상관없이 UI를 렌더링하는 방식이라 호환성이 우수하다고 주장한다.[^25] 또한 Flutter가 안드로이드/iOS뿐 아니라 맥OS, 윈도우, 웹 등 모든 플랫폼을 목표로 계속 확장 중이라고 언급한다.[^25]
강사 개인 경험으로는 React Native와 Flutter를 모두 공부해봤고, Flutter가 더 배우기 쉽고 커뮤니티도 더 잘 되어 있어 앱개발 주력으로 Flutter를 사용하고 있다고 말한다.[^26]
3.3 개발 환경 구축: Android Studio, Flutter 설치, 환경 변수, 플러그인, 프로젝트 생성[^27]
강사는 수업 도구로 Android Studio를 사용해 Flutter 개발을 진행한다고 밝힌다.[^27] 최근 Cursor AI 등 다양한 AI 도구가 있지만 비용 문제가 있고, 무엇보다 AI를 활용하려면 “Flutter 코드 원리”를 알아야 하므로 기본기를 먼저 잡자는 취지라고 설명한다.[^27]
3.3.1 설치해야 할 것들(Windows 기준)과 이유[^28]
- Android Studio 설치: 메모장으로도 개발은 가능하지만 현실적으로 어렵고, IDE의 문법 하이라이트/개발 편의가 필요하다고 말한다.[^28]
- Flutter SDK 별도 설치:
flutter명령어 사용을 위해 환경 변수 설정이 필요하다.[^29] - Android Studio에 Flutter 플러그인 설치: IDE가 Flutter 문법/기능을 이해하도록 하는 단계.[^29]
- Flutter 동작 확인:
flutter doctor로 개발 가능 여부를 진단한다고 설명한다.[^30]
강사는 공식 문서를 보고 설치하는 것을 권장하며, GPT가 답을 주더라도 결국 공식 문서 기반이므로 문서 기반으로 원리를 이해하는 게 중요하다고 말한다.[^31]
3.3.2 Windows 환경 변수(PATH)에 flutter/bin 등록[^33]
Flutter 설치 후 flutter/bin 경로를 시스템 PATH에 추가해야 CMD에서 flutter 명령이 동작한다고 설명한다.[^33]
- 내 PC → 속성 → 고급 시스템 설정 → 환경 변수에서 “시스템 변수의 Path”를 편집해 Flutter
bin경로를 추가하는 과정을 보여준다.[^34] - 이후 CMD에서
flutter를 입력하면 명령 목록이 나오며,flutter doctor는 “의사처럼 진단”해 개발환경을 점검한다고 비유한다.[^30][^35] - 안드로이드 개발을 위해 라이선스 동의가 필요하며,
flutter doctor --android-licenses를 실행하고 질문에y입력/엔터로 진행한다고 안내한다.[^35]
3.3.3 Android Studio 플러그인 설치와 Flutter 프로젝트 생성[^36]
Android Studio에서 Plugins(마켓플레이스)에서 Flutter를 설치하고 IDE를 재시작하면 “New Flutter Project” 메뉴가 생긴다고 설명한다.[^36] “New Project”는 네이티브, “New Flutter Project”가 Flutter 프로젝트라고 구분해준다.[^37]
프로젝트 생성 단계에서:
- Flutter SDK 경로 설정: Flutter 폴더(상위)까지 지정하고
bin은 제외하라고 안내한다.[^38] - 프로젝트 이름 규칙: 소문자 + 언더스코어 권장, 대문자 사용 시 에러가 날 수 있다고 설명한다.[^39]
- 조직명/패키지명(organization):
com.company.app형태로 고유해야 하고, 스토어 배포 시 중복되면 업로드가 안 되므로 신중해야 한다고 강조한다.[^40] - Android/iOS만 체크: 나머지 플랫폼은 아직 지원이 상대적으로 미흡할 수 있어, 앱개발 중심이면 Android/iOS만 선택하라고 말한다.[^41]
3.3.4 실행: 에뮬레이터(AVD) 또는 실기기[^42]
실행 방법은 2가지:
- 에뮬레이터(AVD) 실행
- USB로 스마트폰 연결 후 빌드/설치[^42]
강의에서는 시연을 위해 에뮬레이터를 사용하며, Device Manager에서 디바이스를 선택/생성할 수 있음을 보여준다.[^43] 에뮬레이터가 IDE 내부에 뜨는 경우/외부 창으로 뜨는 경우 설정을 설명하며, Settings에서 emulator 관련 옵션 체크 해제로 외부 창 실행도 가능하다고 말한다.[^44] 에뮬레이터 크기는 단축키(컨트롤+휠/방향키 조합) 등으로 조절 가능하다고 안내한다.[^45]
3.3.5 첫 실행과 Flutter 프로젝트 구조, Hot Reload[^46]
Run을 눌러 기본 카운터 예제가 실행되며, 첫 빌드는 3~5분 정도 걸릴 수 있다고 말한다.[^46] 빌드 중에 프로젝트 구조를 훑는데, Android/iOS 폴더가 있고 실제 Flutter 코드는 lib/main.dart에 있다고 설명한다.[^47]
- 앱 실행의 시작점: 앱 클릭 →
main()함수 실행.[^48] - 위젯 구조:
MyApp같은 위젯 클래스가 실행되고,StatefulWidget/State구조가 있음을 “일단 구조를 보자”는 수준으로 훑는다.[^49] - Hot Reload: 코드에서 색상을 바꾸면 거의 즉시 UI가 바뀌는 것을 보여주며, 이것이 Flutter의 Hot Reload 기능이라고 설명한다.[^50]
- Scaffold 구성요소: AppBar(상단 바), FloatingActionButton(우하단 + 버튼) 등을 지우면 즉시 사라지는 것을 시연하며 개발 속도가 빠르다고 강조한다.[^51]
이 시점에서 “다음은 Dart 언어를 공부해야 한다”고 연결한다.[^52]
3.4 Dart 언어 핵심 5요소(데이터/함수/조건/반복/클래스)와 DartPad 실습[^93]
강사는 언어 학습을 “공부 그 자체”라기보다 “서비스를 만들기 위한 수단”으로 보라고 말한다.[^93] 먼저 생산적인 개발을 하고 필요할 때 공부로 업그레이드하라는 접근을 강조한다.[^93]
언어를 배울 때 공통으로 중요한 5가지로 데이터, 함수, 조건문, 반복문, 클래스를 제시하며, 이것만으로도 백엔드/프런트/앱 개발 대부분을 할 수 있다고 말한다.[^95]
3.4.1 데이터: 단일 값 vs 여러 값(List/Map)[^96]
데이터는 로직 수행에 필수이며 “데이터가 변환되는 것 자체가 로직”이라고 정의한다.[^96] 타입에는 숫자, 문자, bool 등이 있고, 여러 개는 리스트/맵이 있다고 소개한다.[^97]
- 단일 값: int/string/bool/double 등[^97]
- 여러 값:
- List: 순서가 있고 인덱스로 접근[^98]
- Map: key-value로 저장하고 key로 접근[^98]
DartPad(웹에서 다트 실행)로 void main(){ print('hello'); }를 실행해 출력 확인을 하며 실습 중심으로 진행한다.[^99]
(1) 단일 타입 실습: int/string/bool/double[^100]
int a = 10;처럼 숫자를 저장하며, 타입과 맞지 않는 값을 넣으면 안 된다고 설명한다.[^100]String a1 = '안녕';처럼 따옴표로 문자열을 저장하고print(a1)로 출력 확인을 반복해보라고 한다.[^101]bool a2 = true/false만 가능하며, “맞다/아니다” 이지선다 상황이 개발에서 매우 자주 등장하므로 최적화된 타입이라고 설명한다.[^102]double은 소수점 숫자(예: 3.14)이며, 숫자형은 int로도 충분히 커버된다고 언급한다.[^103]
(2) List 실습: 타입 지정, 인덱스(0부터), 범위 오류[^104]
리스트는 “트럭에 짐을 싣고 온다” 비유로, 꺾쇠 <String>은 트럭에 실리는 짐(요소)의 타입을 정하는 것이라고 설명한다.[^104]
List<String> users = ['철수','민지','지원'];처럼 선언하고, 문자열 리스트에 숫자를 넣으면 타입 오류가 난다고 보여준다.[^105]- 인덱스 접근은
users[0]이며, 언어는 0부터 시작한다고 강조한다.[^106] - 존재하지 않는 인덱스(예:
users[3])는 에러가 나며, 자바스크립트는undefined처럼 언어 차이가 있다고 덧붙인다.[^107]
(3) Map 실습: Map<String, dynamic> 패턴, 중첩(List inside Map) 접근[^108]
맵은 Map<키타입, 값타입>이며, 키는 사람이 읽기 쉬운 문자열이 보통이라 String을 많이 쓴다고 설명한다.[^108] 값은 실무에서 문자/숫자/리스트 등 섞이므로 dynamic을 많이 써서 Map<String, dynamic> 패턴이 흔하다고 말한다.[^109]
예시로 {'name':'홍길동','age':20,'items':['노트북','볼펜']} 같은 구조를 만들고:
map['age']처럼 키로 접근[^110]- 중첩 리스트는
map['items'][1]로 볼펜을 꺼내는 시연을 한다.[^110]
(4) var vs dynamic: 동적 타입의 차이[^111]
Dart는 자바스크립트와 자바 성격이 섞여 있으며 var와 dynamic 차이를 강조한다.[^111]
var: 최초 할당 시 타입이 결정되고 이후 바뀌지 않는다.[^112]dynamic: 타입을 자유롭게 바꿀 수 있다.[^113]- 실무에서는 값의 타입이 계속 바뀌는 경우가 드물어서
dynamic은 잘 안 쓰고var를 주로 쓴다고 조언한다.[^114]
3.4.2 널 세이프티(Null Safety): ?, 초기값, late 3가지 방식[^115]
Flutter 최신 버전은 null safety를 적용하며, 값이 없을 수 있는 상황(null)을 컴파일 단계에서 최대한 방지하려는 목적이라고 설명한다.[^115] “박스에서 값을 꺼냈는데 있는 줄 알았더니 없는 것”이 null 에러라는 비유를 든다.[^116]
널 세이프티 처리 방법 3가지:
- 타입 뒤에
?를 붙여 nullable임을 명시 (String? c;)[^117] - 초기값을 지정 (
String c = '';) — 공백과 null은 다르다고 설명[^118] late를 붙여 “나중에 반드시 세팅할 테니 믿어달라”(지연 초기화) — 하지만 세팅 없이 사용하면 런타임 에러 가능[^119]
3.4.3 함수: 재사용, 매개변수(위치/명명), 리턴(return) 개념[^120]
함수는 “여러 로직에 이름(별칭)을 주는 것”이며, 중요한/반복 로직을 호출로 재사용하는 도구라고 정의한다.[^120]
(1) 함수 선언 vs 호출[^121]
void addSixToTwenty(){ ... }처럼 선언하고addSixToTwenty();로 호출한다고 설명한다.[^121]
(2) 매개변수(파라미터): 위치 매개변수 예시[^122]
10+20처럼 고정된 값만 더하면 활용성이 떨어지므로, 함수가 데이터를 받도록 매개변수를 사용해야 한다고 설명한다.[^122]
- 예:
void addTwoNumbers(int number1, int number2){ ... } - 호출 시
addTwoNumbers(10, 50)처럼 매개변수 개수/순서에 맞게 인자를 넣어야 하며, 그렇지 않으면 에러가 난다고 시연한다.[^123]
(3) 리턴(return): 호출한 쪽에서 결과를 “받아야” 다음 로직/UI로 활용 가능[^124]
함수는 로직 수행 후 값을 반환할 수 있으며, 반환 타입은 함수 선언부 타입과 맞아야 한다고 설명한다.[^124]
bool을 리턴하면true/false반환 가능[^124]- “60이 뭔지 아는 것과, 그 값을 받아서 UI로 바꾸는 것은 다르다”는 표현으로, 리턴을 받아 변수에 담아야 실제 활용이 가능하다고 강조한다.[^124]
(4) 명명된 매개변수(named parameter) + required/기본값/nullable 처리[^126]
다트는 중괄호 {}로 감싼 명명된 매개변수를 지원하며, 매개변수가 많아질수록 위치 매개변수는 읽기 어렵고 명명된 방식이 유리하다고 말한다.[^126][^127]
- 명명된 매개변수에서 null safety로 인해:
?로 nullable- 기본값 지정
required로 필수 입력을 강제할 수 있다고 설명한다.[^128]
- 호출 시
func(number1: 10, number2: 20)처럼 키:값 형태로 전달하므로 가독성이 좋다고 한다.[^129]
3.4.4 조건문(if/else if/else): 조건식은 bool을 반환해야 함[^130]
조건문에서 if( ? ) 괄호 안에는 “조건식”이 들어가며, 정확히는 bool(true/false)만 들어갈 수 있다고 강조한다.[^130]
점수 예시로 score == 100 같은 비교 연산을 넣으면 그 비교 결과가 true/false를 리턴하므로 if가 동작한다고 설명한다.[^131]
if가 true면 해당 블록 실행, false면 넘어감[^132]else는 if가 false일 때 실행되는 분기[^132]else if는 추가 조건을 연쇄로 검사하는 구조[^133]
특히 if 체인의 핵심 규칙 2가지를 정리한다:
- 위에서부터 내려오며 “처음 true가 나오면 그 뒤는 보지 않고 전체 탈출”[^134]
- 조건식은 꼭 같은 변수(score)만 검사할 필요 없이 서로 다른 조건식들도 가능하지만, 실무에선 한 데이터에 대해 여러 조건을 묻는 경우가 많으니 깔끔하게 정리하라고 조언한다.[^135]
3.4.5 반복문(for): 0~99 출력, length 기반 순회, for-in 문법[^136]
for(int i=0; i<100; i++) print(i);를 통해 0부터 99까지 출력되는 것을 보여주며, 반복문의 프로세스(초기값→조건식 검사→실행→증가→재검사→탈출)를 단계별로 설명한다.[^136][^137]
백엔드에서 회원 리스트를 받았을 때 UI로 보여주려면 “한 번에 변경되지 않으므로” 반복으로 하나씩 꺼내 UI로 변환해야 한다는 맥락을 다시 연결한다.[^98][^138]
members.length를 사용해 데이터 개수가 달라져도 안전하게 순회하도록 설명한다.[^138]for (var m in members)형태의 for-in 문법도 가능하며, 원리는 결국 인덱스를 증가시키며 꺼내는 것이라고 정리한다.[^139]
3.4.6 클래스(Class): 규격화된 복합 타입, 생성자, this, 메서드, 네임드 생성자 패턴[^140]
강사는 클래스가 객체지향 등으로 어렵게 느껴질 수 있으나, 본인 관점에서는 “여러 값을 받는 데이터 타입”이라고 정의한다.[^140] 리스트/맵도 여러 값을 담지만, 클래스는 “정해진 항목(필드)만 들어가는 규격”이 있다는 점이 다르다고 말한다.[^141]
(1) 클래스가 필요한 이유: 같은 패턴 데이터 관리[^142]
강아지/고양이 나이 같은 유사한 데이터 패턴이 많고, 이를 변수로 흩뿌리면 관리가 힘들다.[^142]
맵을 쓰면 기준이 없어 아무 키나 들어갈 수 있으니(규격 없음) 애매하고, 이럴 때 클래스로 규격화하면 좋다고 설명한다.[^142][^143]
(2) Animal 클래스 예시: 필드 + 생성자 + this[^144]
class Animal { String type; int age; ... }처럼 필드를 만들고, 생성자(클래스명과 동일)를 함수처럼 정의해 값을 세팅한다고 설명한다.[^144]
생성자에서 파라미터와 필드 이름이 겹칠 수 있으므로 this.type = type;처럼 this로 “현재 클래스의 필드”임을 명확히 하라고 말한다.[^145]
null safety 에러는 초기값 제공 또는 nullable/late 등으로 해결할 수 있음을 언급한다.[^146]
이후 Animal dog = Animal('강아지', 2);처럼 인스턴스를 만들고, 점(.)으로 필드 접근(dog.type)이 가능함을 보여준다.[^147]
(3) 객체 지향의 직관: “속성 추가는 클래스에 한다”[^148]
“이름(name) 필드를 추가하려면 어디에 작업하냐? 클래스에 한다”는 예로, 우리가 자연스럽게 객체를 중심으로 기능/데이터를 확장하는 것이 객체지향이라고 설명한다.[^148]
(4) 클래스 안에 함수(메서드) 추가 + 문자열 보간(interpolation)[^149]
클래스에는 필드뿐 아니라 함수도 넣을 수 있으며, 예로 sayHello() 메서드를 만들고 print('... ${this.type} ...') 형태의 문자열 보간을 설명한다.[^149]
인스턴스에서 dog.sayHello()처럼 호출할 수 있고, 수정이 필요하면 클래스 내부만 바꾸면 되어 분화/유지보수에 유리하다고 정리한다.[^150]
(5) 네임드 파라미터 스타일의 생성자(가독성) 소개[^151]
Flutter 위젯들이 키:값 형태를 많이 쓰는 이유를 “명명된 생성자/파라미터가 가독성이 좋기 때문”이라고 연결한다.[^151]
생성자에서 { this.type, this.age } 형태로 받고 기본값을 둘 수 있으며, 호출 시 Animal(type: '강아지', age: 2)처럼 작성해 필드가 많아져도 읽기 좋다고 말한다.[^151]
3.5 Dart를 알고 나서 Flutter 기본 코드 다시 읽기: “전부 클래스 + 키밸류” 관점[^152]
Dart 학습 후 다시 main.dart를 보면:
main()에서 Flutter 내장 함수runApp()을 호출한다.[^152]StatelessWidget/StatefulWidget은 Flutter 팀이 제공한 클래스를 상속해 기능을 “한 줄로 가져다 쓰는” 방식이며, 상속은 다른 클래스 내용을 내 클래스로 가져오는 것이라고 설명한다.[^153]MaterialApp,ThemeData,Scaffold,AppBar,body등도 전부 클래스이고, 속성들이 키:값 형태로 이어진다는 점을 강조한다.[^154]
결론적으로 Flutter UI는 “키값에 무엇을 넣으면 어떤 UI/기능이 되는지”를 문서/AI로 확인하며 조립하는 방식이며, 이제 코드가 “할 만하게” 느껴질 것이라고 말한다.[^155]
3.6 페이지/폴더 구조 만들기: pages/index_page.dart + 단축 생성(STF)[^156]
기존 MyHomePage 부분을 정리하고, lib 폴더가 1차원으로 파일이 많아지면 보기 힘들므로 디렉토리로 관리하자고 제안한다.[^156]
lib/pages/디렉토리 생성[^157]index_page.dart생성[^157]- Android Studio에서
stf를 입력해StatefulWidget템플릿을 자동 생성하고 클래스명은IndexPage처럼 대문자로 시작한다고 설명한다.[^158] material.dart임포트를 추가한다.[^159]main.dart의 home을IndexPage()로 바꾸어 첫 화면을 교체한다.[^160]
실행하면 Placeholder 수준의 화면이 뜨며, 이후 디자인/UI를 넣어갈 것이라고 말한다.[^161]
또한 AI로 UI를 빠르게 뽑을 수 있는 시대지만, 유지보수/협업/소통을 위해 개발자가 기본 원리는 알아야 한다고 강조한다.[^162]
3.7 기본 위젯과 레이아웃: Scaffold/Container/Column/Row, 정렬 축(Main/Cross), 이미지, 텍스트 스타일, 패딩/사이즈박스, 입력창, 버튼[^185]
강사는 위젯 소개를 노션/PDF 자료와 함께 진행하며, Flutter에서 앱 화면을 구성하는 대표 위젯들을 설명·실습한다.[^185]
3.7.1 Scaffold: 앱 기본 골격(건물 “거푸집” 비유)[^186]
Scaffold는 AppBar, Body, Drawer(슬라이드 메뉴), BottomNavigationBar, FloatingActionButton 등 앱에서 흔히 쓰는 기본 요소를 지원하는 “틀”이라고 설명한다.[^186] 구글에서 scaffold 뜻을 찾아보면 건물의 거푸집/기본 틀 같은 의미이며, Flutter는 기능을 제공해두고 “쓰고 싶으면 적고, 안 쓰면 안 적으면 된다”는 철학이라 개발 속도가 빠를 수 있다고 말한다.[^187]
3.7.2 Container: 네모 박스(웹의 div 비유)[^188]
Container는 네모 박스이며 웹 개발자에겐 div와 비슷하다고 설명한다.[^188] 박스이므로 width/height, background color 등 조절이 가능하고, UI는 결국 박스를 배치/늘리고 내부에 글자·버튼을 넣어 만든다고 본다.[^188]
3.7.3 위젯/속성은 외우는 게 아니라 “찾아서 쓴다” + 타입 확인[^189]
위젯과 속성은 매우 많아 외우는 것이 아니라 문서/검색/AI로 찾아서 쓰면 된다고 말한다.[^189] 다만 문법은 타입 기반이므로 “문자가 들어가야 하는데 숫자를 넣으면 안 된다”처럼 타입을 파악할 수 있어야 한다고 강조한다.[^190]
3.7.4 Column/Row: 정렬의 핵심, 99.9%는 Column부터 시작[^191]
정렬 위젯인 Column/Row는 매우 중요하며:
- Row: 가로로 여러 위젯
- Column: 세로로 여러 위젯[^191]
앱 UI는 대체로 위에서 아래로 내려가기 때문에 페이지 body에 여러 위젯을 넣을 때 99.9%는 Column을 먼저 둔다고 말한다.[^192] 그리고 Column 내부 일부 구간에서 좌우 배치가 필요하면 Row를 넣는 식으로 조립한다고 설명한다.[^192]
3.7.5 Container 속성 힌트 읽기: 자동완성에서 타입/nullable 파악[^193]
Android Studio 자동완성(옵션 목록)을 보면 color, width, height, decoration 등이 나오고, 타입과 nullable 여부도 표시되어 “안 넣어도 되는지(널러블)” 등을 확인할 수 있다고 설명한다.[^193] decoration처럼 또 다른 클래스가 요구되면 그 내부 속성을 다시 찾아가며 구성해야 하며, 결국 이 정보를 제공하는 공식 문서가 중요하다고 연결한다.[^194]
3.7.6 화면 크기 대응: 고정 px가 아니라 double.infinity 등 반응형 사고[^195]
Container를 300/400 같은 고정 크기로 만들면 폰 사이즈가 다양한 현실에서 빈 공간이 생길 수 있다고 경고한다.[^195] 그래서 width/height에 double.infinity를 주어 가능한 영역을 채우도록 만들 수 있다고 시연한다.[^195]
3.7.7 Column 정렬 축 개념: MainAxis vs CrossAxis[^196]
Column은 자식이 “세로로 진행”하므로 그 진행 방향이 MainAxis(주축), 그 직각이 CrossAxis라고 설명한다.[^196] Row는 반대로 가로가 MainAxis이다.[^196] 문서 편집기의 가운데정렬/끝정렬과 유사하게:
- start/center/end
- spaceBetween 등 균등 배치
같은 속성으로 정렬을 조정한다고 설명하고, 직접 center/end/spaceBetween을 바꿔보며 결과를 확인하라고 한다.[^197]
3.7.8 Image.network: 네트워크 이미지 표시 + 크기 조절[^198]
Image.network(url)로 이미지 주소를 넣어 표시할 수 있고, width/height로 크기 조절도 가능하다고 보여준다.[^198]
3.7.9 Text 스타일: TextStyle로 글자 크기/색/굵기 + “반복 스타일은 변수로 분리”[^199]
“텍스트 글자 크기/색” 같은 것은 GPT에 물어보면 style: TextStyle(...)로 알려준다고 보여주며, 실제로 color, fontWeight, fontSize 등을 적용한다.[^199]
하지만 같은 스타일을 여러 텍스트에 적용하려면 반복 작성이 생기므로, TextStyle ts1 = TextStyle(...);처럼 빌드 상단에 변수로 빼서 재사용하라고 조언한다.[^200] 웹의 CSS 클래스처럼 Flutter는 코드 레벨에서 스타일 데이터를 변수로 관리하는 관점이라고 설명한다.[^200]
강사는 “언어 자체보다 Flutter 개발을 많이 해봐야 한다”는 메시지를 재차 강조하며, 현업 개발자도 공부를 끝내고 개발하는 것이 아니라 “만들면서 공부한다”고 말한다.[^201]
3.7.10 간격 주기: Padding vs SizedBox + 단축(Alt+Enter) 활용[^202]
위젯 사이 간격을 줄 때:
- Padding: 위젯을 감싸 투명한 튜브를 끼운다는 비유로 설명한다.[^202]
- SizedBox: 빈 공간만 차지하는 박스로 빠르게 간격을 준다.[^203]
단축키(Windows 기준 Alt+Enter)로 위젯을 Padding으로 감싸는 등 IDE 지원을 활용할 수 있다고 보여준다.[^202]
3.7.11 Row 배치: mainAxisAlignment로 가운데/양끝 배치 패턴[^204]
Row에서 텍스트들을 옆으로 나열하고, mainAxisAlignment: MainAxisAlignment.center 또는 spaceBetween으로 가운데/양끝 배치를 구현하는 패턴이 메뉴/버튼 배치에서 자주 쓰인다고 설명한다.[^204]
3.7.12 TextFormField/TextField: 입력 이벤트(onChanged)와 컨트롤러(TextEditingController)[^205]
텍스트 입력 위젯을 추가하고, 에뮬레이터 키보드로 입력이 가능함을 시연한다.[^205]
onChanged는 문자 변경마다 호출되어 값을 출력(print)할 수 있다.[^206]- 실무에서는
TextEditingController를 더 많이 쓰며, 컨트롤러로 값을 저장하고 버튼 클릭 시 접근해 꺼내는 패턴을 설명한다.[^207]
3.7.13 버튼(ElevatedButton)과 입력값 접근 예시[^208]
ElevatedButton(onPressed: ..., child: Text('버튼1')) 형태로 버튼을 만들고, 눌렀을 때 컨트롤러의 텍스트를 읽어 출력하거나 로직에 사용할 수 있음을 보여준다.[^208]
3.7.14 상태(State)와 setState: “데이터 변경 + 리빌드”가 핵심[^220]
강의는 “버튼을 눌렀을 때 텍스트(안녕→헬로)를 바꿔보자”는 실습으로 상태 개념을 설명한다.[^220]
- 처음엔 텍스트가 코드에 하드코딩되어 있어 버튼을 눌러도 UI가 바뀔 수 없음을 지적한다.[^220]
- 텍스트 값을
String helloText = '안녕';같은 변수로 빼고, 버튼에서helloText = '헬로';로 바꾸면 데이터는 바뀌지만 UI는 그대로임을 보여준다(콘솔 print로 값 변경은 확인되지만 화면은 안 바뀜).[^221] - 이유: 프론트(UI)는 “데이터가 바뀌면 UI도 바뀔 것”이라는 개발자 생각과 달리, 실제로는 UI를 다시 그려야 한다고 강조한다.[^222]
- 해결:
setState(() { helloText = '헬로'; });로 상태 변경을 감싸면 “값 변경 + 다시 그리기”가 수행되어 UI가 갱신된다.[^228]
이 개념은 React의 state와 동일한 계열로 비유하며, Flutter는 setState, React는 useState 같은 메커니즘이라고 설명한다.[^223]
또한 텍스트뿐 아니라 이미지 크기 같은 UI 속성도 전역 변수로 빼고 setState로 변경하면 즉시 UI가 바뀐다고 시연한다.[^229] 결론적으로 “UI에 반영되어야 하는 값은 상태로 빼고 setState로 변경한다”가 핵심이라고 정리한다.[^230]
강사는 이번 파트를 정리하며:
- 페이지 만들기
- 위젯 몇 개 직접 사용
- Column/Row로 정렬
- 전역 변수 + setState로 실시간 UI 변경
을 수행했고, 다음은 REST API로 서버에서 데이터를 받아 보여주는 것을 하겠다고 예고한다.[^231]
3.8 REST API + HTTP 통신: 패키지 추가, 요청 타이밍(initState), Future/async/await, JSON decode, setState 반영[^248]
강사는 앱이 서비스가 되려면 서버/DB가 필수이며, 앱만으로는 다른 폰에서 로그인해도 데이터가 없고 타인의 데이터를 보려면 서버가 필요하다고 말한다.[^248] 프런트엔드의 중요한 역할이 서버에 요청해 데이터를 불러와 UI에 보여주는 것이라며 REST API를 다룬다.[^249]
3.8.1 REST API 개념: URL 주소로 데이터 송수신[^250]
REST는 DB에서 정보를 주고받는 방식, API는 프로그램 간 연결 매개체라고 설명하며, REST API는 앱(Flutter)과 DB 사이에 백엔드 서버(URL)를 두고 그 주소로 데이터 통신하는 것이라고 정리한다.[^250]
3.8.2 실습용 API: JSONPlaceholder (todos)[^251]
학습용 무료 Fake REST API인 JSONPlaceholder를 소개하고, /todos/1로 단일 데이터, /todos/2로 다른 데이터, /todos로 200개 목록을 받을 수 있음을 보여준다.[^251]
이때 받는 데이터는 JSON이며 “문자열 기반 데이터”지만, 나중에 특정 타입(List/Map 등)으로 변환해 쓸 수 있다고 설명한다.[^252]
3.8.3 TodoPage 생성 + Navigator.push로 페이지 이동[^254]
todo_page.dart를 만들고 TodoPage(Stateful) + Scaffold/AppBar/Column/Center/Text로 기본 UI를 만든다.[^254]
IndexPage에서 버튼을 만들어 Navigator.push(context, MaterialPageRoute(builder: (_) => TodoPage())) 같은 방식으로 이동한다.[^255]
강사는 push는 기존 페이지 위에 쌓는 스택 구조라고 설명하며, 너무 많이 쌓이면 앱이 무거워질 수 있으니 라우팅 전략(예: 채팅방 들어갔다 나오는 흐름처럼)을 잘 설계해야 한다고 조언한다.[^256]
3.8.4 “요청을 언제 할 것인가”: build가 아니라 initState(라이프사이클)[^257]
서버 요청을 build 메서드에 넣으면 setState로 리빌드될 때마다 요청이 반복되어 비효율/버그가 될 수 있다고 경고한다.[^257]
앱/위젯에는 생명주기(lifecycle)가 있고, 보여질 때/바뀔 때/사라질 때 특정 함수가 호출되며, 대표적으로 initState()에 초기 서버 요청을 넣는다고 설명한다.[^257]
3.8.5 http 패키지 추가(pub.dev) + 별칭 import[^258]
Flutter에서 REST 호출에 많이 쓰는 패키지로 http와 dio가 있는데, 여기서는 http를 사용한다고 한다.[^258]
pub.dev에서 http를 찾아 pubspec.yaml의 dependencies에 추가하고 pub get으로 다운로드하는 과정을 보여준다.[^259]
또한 import 'package:http/http.dart' as http;처럼 별칭을 두는 이유는 get/post/... 같은 함수명이 짧아 다른 함수와 이름 충돌 가능성이 있어 http.get()처럼 점 접근을 권장하기 때문이라고 설명한다.[^260]
3.8.6 Future/async/await: “음식 주문” 비유로 비동기 이해[^261]
http 요청 함수는 Future를 반환하는데, Future는 “지금 당장 결과가 없고 나중에 올 것”이라는 의미로 설명한다.[^261]
“음식 주문하고 바로 나왔냐고 묻는 것”이 Future를 await 없이 다루는 상황이며, 음식을 받으려면 기다려야 하듯이 await로 기다려 결과를 받는다고 비유한다.[^262]
그래서 함수에 async를 붙이고 final response = await http.get(...) 형태로 받은 뒤, response.body가 JSON 문자열이라고 설명한다.[^263]
또한 요청이 안 될 때는 header를 추가해야 하는 경우가 있어 headers를 넣는 수정도 시연한다.[^264]
3.8.7 JSON 문자열 → Map/List 변환: jsonDecode, dynamic, 키 접근[^265]
response.body는 String이라서 곧바로 ['title'] 같은 Map 접근이 안 된다고 지적한다.[^265]
jsonDecode(response.body)를 쓰면 자동으로 적절한 타입(Map/List)으로 변환되며, 반환 타입은 상황에 따라 달라 dynamic으로 본다고 설명한다.[^266]
변환 후 json['title']로 title을 꺼내 출력하는 것을 시연하고, URL의 id를 바꾸면 다른 title이 나오는 것도 확인한다.[^267]
또한 함수 매개변수로 int id를 받아 URL 문자열 보간(.../todos/$id)으로 일반화할 수 있다고 설명한다.[^268]
3.8.8 UI에 반영: String title 상태 + setState로 화면 표시[^269]
받아온 타이틀을 화면에 보여주기 위해:
String title = '초기값';상태를 만들고[^269]- 데이터를 받은 뒤
setState(() { title = json['title']; });로 반영[^269] - Text 위젯에서
title을 보여주도록 수정
하는 방식으로 “배운 것의 조합”으로 구현 가능하다고 강조한다.[^270]
3.9 모델(VO) 클래스로 JSON 매핑: Todo 클래스 + fromJson(factory)로 코드 정리[^302]
강사는 title 하나가 아니라 id/userId/completed 등 필드가 늘어나면 UI 코드에서 일일이 꺼내는 방식이 비효율적이라고 지적한다.[^302] 실제 개발에서는 필드가 40~50개까지 늘 수 있고, 이때 Flutter 문서에서도 “커스텀 오브젝트(모델)로 받자”는 패턴이 있다고 설명한다.[^302]
그래서 lib/vo/(또는 model 폴더) 디렉토리를 만들고 Todo 클래스를 생성한다.[^303]
3.9.1 Todo 필드/생성자 설계[^304]
int idint userIdString titlebool completed
같은 필드를 선언하고 생성자를 만든다.[^304]
required로 전부 강제하기보다 기본값을 주어 유동적으로 쓰는 설계가 실무에서 편할 때가 많다고 말한다(회원가입에서 필수 필드만 받는 것처럼).[^305]
3.9.2 fromJson(factory)로 Map→Todo 변환[^306]
핵심은 “JSON(Map)을 Todo 객체로 바꾸는 변환 함수”이며, 보통 Todo.fromJson(Map<String, dynamic> json) 형태로 만든다고 설명한다.[^306]
factory는 재사용/규칙상 붙이는 형태로 소개하고, 내부에서 return Todo(id: json['id'], ... )처럼 값을 매핑한다.[^307]
이 과정은 반복 작업처럼 보일 수 있으나(예전엔 직접 다 쳤다), 요즘은 AI가 생성해도 “이게 Map을 Todo로 바꿔주는 코드”라는 의미를 이해해야 한다고 강조한다.[^308]
3.9.3 UI 코드에서 Todo 객체만 들고 쓰기 + null 처리[^309]
TodoPage 쪽에서는:
Todo? todo;처럼 상태로 두고(처음엔 null일 수 있음)[^309]- 요청 후
final t = Todo.fromJson(json); setState(() { todo = t; });로 상태 반영[^310] - UI에서는
todo?.title ?? '없음'처럼 null-safe 접근을 사용해 로딩/빈 상태를 처리할 수 있다고 설명한다.[^311]
그 결과 title/id/userId/completed 등을 todo?.id 같은 형태로 간단히 출력할 수 있고, 변환 로직을 모델로 옮겨 UI 코드가 정리되는 “개선”이 이루어진다고 정리한다.[^312]
3.9.4 다음 과제 예고: 상태관리(Provider)로 UI와 비즈니스 로직 분리/공유[^313]
강사는 현재 구조의 다음 문제를 제시한다:
- 다른 위젯/컴포넌트에서도 todo 데이터를 쓰려면 비슷한 코드를 다시 짜야 하는 문제[^313]
- UI 코드와 데이터 처리(비즈니스 로직)가 섞여 코드가 보기 힘들어지는 문제[^313]
그래서 데이터 공유와 로직 분리를 위한 “상태 관리” 개념(Provider 등)을 다음에 다루겠다고 예고하며 마무리한다.[^314]
4. 핵심 통찰[^6]
- Flutter 학습의 출발점은 “위젯 문법 암기”가 아니라 앱 개발 방식의 트레이드오프 이해와 크로스플랫폼의 구조적 이점을 잡는 것이다.[^12][^25]
- Dart는 어려운 문법을 많이 아는 것보다, 데이터/함수/조건/반복/클래스 5요소를 “서비스를 만드는 관점”에서 조합하는 능력이 핵심이다.[^95][^93]
- Flutter UI는 클래스(위젯) + 키:값 속성 조합이며, 대부분의 위젯 사용법은 문서/AI로 “찾아 쓰되”, 타입/널러블을 읽는 눈이 있어야 한다.[^154][^193]
- 프런트 개발의 본질은 “데이터 변화”가 아니라 리빌드 트리거다. Flutter에서는
setState가 그 트리거이며, UI에 반영될 값은 상태로 관리해야 한다.[^222][^228] - 서버 통신은 언제 호출할지(initState) 와 비동기(Future/await) 가 관건이며, 응답(JSON 문자열)을 파싱(jsonDecode) 하고 상태 반영(setState) 까지 이어져야 화면에 나타난다.[^257][^261][^269]
- 데이터가 커질수록 “필드 하나씩 꺼내기”는 붕괴한다. 모델(VO) + fromJson 매핑으로 데이터 구조를 규격화하면 UI 코드가 단순해지고 유지보수성이 올라간다.[^302][^306]
- 실행 행동(강의가 암묵적으로 권하는 실천)
pubspec.yaml추가 패키지 설치 흐름(pub.dev → dependencies → pub get)을 실제로 반복해 익숙해질 것.[^259]build()에 무거운 로직(서버 호출)을 넣지 말고initState()같은 라이프사이클에 배치할 것.[^257]- UI에 영향을 주는 값은 전역(상태)로 빼고
setState()로 업데이트하는 패턴을 손에 익힐 것.[^229][^230] - JSON 응답은 즉시 화면에 박지 말고, 모델 클래스로 매핑해 “UI/로직 분리”의 기반을 만들 것.[^312][^313]
5. 헷갈리는 용어 정리[^6]
네이티브 앱: 플랫폼 고유 언어/SDK로 각각 개발하는 방식(Java/Kotlin, Swift 등).[^15]
웹뷰(WebView): 앱 내부에서 웹사이트(URL)를 화면 전체에 띄우는 컴포넌트/방식.[^19]
하이브리드 앱(강의 정의): 웹 프런트 코드를 앱 내부에 포함해 웹뷰로 실행하는 방식(깜빡임↓, 웹뷰 한계 존재).[^23]
크로스플랫폼: 코드 1개로 안드로이드/iOS 등을 동시에 개발·배포하는 방식.[^24]
위젯(Widget): Flutter UI를 구성하는 모든 요소(화면의 부품이자 구조 단위).[^7]
Scaffold: AppBar/Body/FAB/BottomNav 등 화면 기본 골격을 제공하는 위젯.[^186]
Hot Reload: 코드를 저장/변경하면 빠르게 UI 변경을 반영해 확인하는 기능.[^50]
StatefulWidget: 상태 변화에 따라 UI를 다시 그릴 수 있는 위젯 타입.[^49]
setState: 상태 변경을 Flutter에 알리고 해당 위젯을 리빌드하게 하는 메서드.[^228]
REST API: URL 주소를 통해 앱과 서버/DB가 데이터를 주고받는 방식(강의에서는 URL 자체를 강조).[^250]
http 패키지: Flutter/Dart에서 HTTP 요청을 보내기 위한 패키지(pub.dev에서 설치).[^258]
Future / async / await: 비동기 처리(결과가 나중에 오는 작업을 기다려 받는 구조).[^261][^262]
JSON: 문자열 기반 데이터 포맷이며 Map/List 등으로 변환해 사용.[^252][^265]
모델/VO(Value Object): 서버에서 받은 데이터를 앱 내부에서 규격화해 표현하는 클래스(예: Todo).[^302][^304]
fromJson: JSON(Map)을 모델 객체로 변환하는 관례적 메서드/팩토리 생성자 패턴.[^306]
참고(콘텐츠 정보)[^1]
- 제목: Flutter 입문 2시간 무료강의 - 모바일 앱 개발 실습 포함 | (주)올리고컴퍼니 기술이사 홍정민[^1]
- 채널: 메타코드M[^1]
- 길이: 135분 7초[^1]
- 링크: https://www.youtube.com/watch?v=mOtWvKkvC7A[^1]
[^1]: @[00:02]~ "Flutter 입문 2시간 무료강의..." 영상 전체(메타코드M).
[^2]: @[00:04] "키사에서 진행하는 웹테크 미드업... 플러터 강의를 맡게 된 홍정민..."
[^3]: @[00:14]~@[00:24] 올리고컴퍼니 기술이사/개발총괄, K-디지털 강의 진행 소개.
[^4]: @[00:36] "현업의... 실무적인 기술들을 최대한... 전달"
[^5]: @[01:02]~@[01:12] PDF + 노션 자료 안내.
[^6]: @[01:12]~@[01:26] 코드 중심 진행, 개념은 자료로 보완.
[^7]: @[01:40]~@[02:08] 목차: 모바일 앱 방식, Dart, 위젯, 상태관리, REST/HTTP, Provider 등.
[^8]: @[02:15]~@[02:23] 순서는 유동적으로 진행.
[^12]: @[02:35]~@[02:57] 모바일 OS(안드로이드/iOS)와 앱 정의.
[^13]: @[03:23]~@[03:28] 네이티브/웹/하이브리드/크로스플랫폼 4가지 소개.
[^14]: @[03:06]~@[03:17] 플랫폼별 언어/패턴 차이로 인한 개발 방식 차이.
[^15]: @[03:34]~@[03:47] 네이티브 정의와 예시 언어.
[^16]: @[03:49]~@[03:55] 네이티브 장점(성능/반응성)과 단점(코드베이스 2개).
[^17]: @[04:04]~@[04:10] 인력 두 배 필요 문제.
[^18]: @[04:22]~@[04:30] 네이티브 적합 경우/요즘 폰 성능으로 타방식도 잘 돌아감.
[^19]: @[04:36]~@[04:54] 웹/웹뷰 방식 설명.
[^20]: @[04:54]~@[05:12] 웹 장점: 배포 빠름, 딥한 앱 공부 불필요.
[^21]: @[05:16]~@[05:34] 웹 단점: 웹처럼 보임(깜빡임/전환/애니메이션 차이).
[^22]: @[05:39]~@[05:57] 웹 적합: 컨텐츠 중심, 빠른 배포.
[^23]: @[06:01]~@[06:58] 하이브리드 정의, 깜빡임 없음/웹뷰 성능 한계.
[^24]: @[07:09]~@[08:29] React Native 크로스플랫폼, 장점/단점(분기, 복잡 기능).
[^25]: @[08:45]~@[09:26] Flutter 발표, Dart, “흰 도화지” 비유, 멀티플랫폼 지향.
[^26]: @[09:39]~@[09:57] 강사 개인 경험: Flutter가 쉽고 커뮤니티 좋음, 주력 사용.
[^27]: @[10:13]~@[10:31] Android Studio로 기본 원리 학습, AI 도구는 이후 활용.
[^28]: @[10:58]~@[11:11] 메모장 개발은 힘듦, IDE 필요.
[^29]: @[11:26]~@[11:44] Flutter 설치/환경변수/플러그인 설치 흐름.
[^30]: @[16:23]~@[16:30] flutter doctor를 “의사처럼 진단” 비유.
[^31]: @[14:03]~@[14:26] GPT 의존보다 공식문서 기반 원리 이해 강조.
[^33]: @[13:13]~@[13:26] flutter/bin 경로와 환경변수 설정 필요.
[^34]: @[14:56]~@[15:49] Windows 환경변수(Path) 편집 과정.
[^35]: @[16:12]~@[16:54] CMD에서 flutter 확인, android licenses 명령 안내.
[^36]: @[17:19]~@[17:55] Android Studio 플러그인(Flutter) 설치/재시작.
[^37]: @[17:59]~@[18:16] New Project(네이티브) vs New Flutter Project 구분.
[^38]: @[18:23]~@[18:34] Flutter SDK 경로 지정(Flutter 폴더까지만).
[^39]: @[18:47]~@[19:14] 프로젝트명 소문자+언더스코어, 대문자 에러 가능.
[^40]: @[19:30]~@[20:46] 조직명/패키지명 고유성, 스토어 중복 불가, 노출됨.
[^41]: @[21:13]~@[21:51] Android/iOS만 체크, 나머지 플랫폼은 지원 미흡 언급.
[^42]: @[22:30]~@[23:06] 실행 방법: 에뮬레이터 vs 실기기 USB.
[^43]: @[23:06]~@[23:27] Device Manager에서 디바이스 선택/생성.
[^44]: @[24:04]~@[24:15] 에뮬레이터 외부창 설정(체크 해제) 안내.
[^45]: @[24:25]~@[24:38] 에뮬레이터 사이즈 조절 안내.
[^46]: @[25:10]~@[25:22] 첫 빌드 3~5분 걸릴 수 있음.
[^47]: @[25:31]~@[25:55] 프로젝트 구조: android/ios, lib/main.dart.
[^48]: @[27:52]~@[28:00] 앱 실행 시 main 함수 실행.
[^49]: @[28:00]~@[28:58] 위젯 구조(Stateless/Stateful) 훑기.
[^50]: @[28:10]~@[28:23] 색 변경 즉시 반영=Hot Reload.
[^51]: @[29:26]~@[29:59] Scaffold/AppBar/FAB 삭제 시 즉시 반영 시연.
[^52]: @[30:07]~@[30:15] 다음으로 Dart 언어 학습 연결.
[^86]: @[30:19]~@[30:45] Dart 학습 시작, 초심자 맞춤 설명 예고.
[^93]: @[30:53]~@[31:15] 언어는 서비스 만들기 위한 수단, 먼저 생산적 개발.
[^95]: @[31:21]~@[31:38] 언어 핵심 5요소: 데이터/함수/조건/반복/클래스.
[^96]: @[31:46]~@[31:58] 데이터 변환=로직 관점.
[^97]: @[32:00]~@[32:06] 타입 종류(숫자/문자/bool/list/map).
[^98]: @[32:08]~@[32:58] 단일 vs 복수(List/Map), 인덱스 vs 키 접근.
[^99]: @[35:50]~@[36:27] DartPad 실행, hello 출력.
[^100]: @[36:35]~@[37:19] int 선언/타입 일치 설명.
[^101]: @[37:31]~@[38:06] String 선언/따옴표/print 확인.
[^102]: @[38:08]~@[38:31] bool은 true/false만, 이지선다 상황.
[^103]: @[38:37]~@[38:46] double 소수점 예시.
[^104]: @[38:51]~@[39:26] List<타입> 비유(트럭/짐).
[^105]: @[39:39]~@[39:46] List