저번 포스팅에 이어, 밑의 교재 chapter 4 부분을 공부해보려고 한다
https://product.kyobobook.co.kr/detail/S000208993133
1) ui작업 (위젯)
- 위젯은 플러터에서 ui를 구성하는 기본 단위
- 플러터 앱 개발은, 위젯이라는 레고 블록들을 이리저리 결합하고 반복해서 사용하는 작업의 연속
- 선언형 ui : 플러터의 위젯은 바깥으로부터 입력된 필드 값과 상태에 따라 다르게 보인다 -> 개발자가 직접 ui를 변경하지 않고, 상태값의 변경에 따라 위젯이 스스로를 업데이트함
- 즉 ui는 상태의 함수
2) 리액트의 컴포넌트, 플러터의 위젯
- 리액트의 컴포넌트와 플러터의 위젯의 공통점
: 리액트가 컴포넌트 단위로 ui를 구성한다면, 플러터는 위젯 단위로 ui를 구성함
: 리액트와 플러터는 컴포넌트/위젯을 재사용할 수 있음
: 컴포넌트와 위젯 모두 선언형으로 ui를 작성
: 컴포넌트와 위젯 모두 상태(state)를 가질 수 있다(단, 플러터에는 상태를 가질 수 없는 stateless위젯이 존재)
- 리액트의 컴포넌트와 플러터의 위젯의 차이점
: 리액트는 기본적으로 웹 프론트엔드 라이브러리이므로, 최하위 컴포넌트로 내려가면 htlm 요소들이 사용됨 / 반면 플러터에서의 최하위 컴포넌트들은 보통 머터리얼 위젯(텍스트,아이콘 등) 임
: 리액트는 클래스 혹은 함수로 컴포넌트 생성이 가능하고 함수가 보편적이지만, 위젯은 기본적으로 클래스 형태
3) stateless 위젯과 stateful 위젯
stateless 위젯 | stateful 위젯 |
상태를 포함하지 않는 위젯, Provider등의 전역상태는 사용 가능 | 상태를 포함하는 위젯 위젯 본체, 위젯 상태가 별개 클래스로 구분됨 로직 및 ui는 본체가 아닌 위젯 상태 클래스에 작성 |
build 메소드 : 완성된 위젯 타입의 ui 반환 | build 메소드 : stateful 위젯 클래스가 아닌 state 클래스의 인스턴스에 존재, 완성된 위젯 타입의 ui 반환 createState 메소드 : 위젯 내부에서 상태 생성 initState 메소드 : 상태 초기화 setState : 상태 변경 시, 해당 메소드의 콜백함수 내에 상태 변경 로직을 넣어야 ui에 반영됨 (객체의 내부 상태가 변경되었다는걸 플러터에게 알림 / 입력값으로 함수가 들어가고, 이 함수에서 변경을 수행해야 ui가 업데이트 된다는 점을 기억하자) |
4) 플러터 기본 위젯
- 텍스트,아이콘,이미지 : 가장 기본 단위의 위젯 - 주로 위젯 트리 맨 끝에 위치(즉 자식위젯 가지지 않음)
- 레이아웃 : 위젯의 배치에 주로 관여 - 자식위젯을 받아 표시 -> Container, Row, Column, Stack
(1) Container : 기본적 채우기, 위치 조정, 크기 조정을 결합한 편의성 위젯 -> 기본 ui 요소 만들어내는 단위
(2) Row, Column : 컨테이너와 같은 ui 요소들을 각각 가로,세로로 배치하는 위젯 - 자식 여러개 받음
(3) Stack : 겹겹이 쌓이는 ui요소들을 배치하는 위젯 - 가로축, 세로축과 같은 또 하나의 축 -> stack을 사용하면 하나의 위젯이 다른 위젯 위에 떠있는 것 처럼 만들 수 있다
- 이외에도 Padding, ListView, GridVirew, AspectRatio, SizedBox 등이 있다
- Flex, 그리고 그 자식으로 Flexible을 이용하고 개별 Flexible들에 flex 값을 주면, 상대적 길이를 가진 컨테이너를 만들 수 있다(flex 기본값 1)
- 입력,폼 : 사용자의 입력을 받고 사용자와 상호작용하는 위젯 - 주로 상태관리 및 서버 호출과 연관
* ElevatedButton : 시각적 입체효과 있는 버튼
- 머터리얼 구성요소, 제스처, 기타 : MaterialApp, Material, Scaffold, AppBar, BottomNavigationBar, GestureDetector 등
* Column vs ListView : 여러 위젯을 위에서 아래로 나열하는건 같지만, ListView는 스크롤에 최적화되어있음 -> 스크롤 없이 모든 항목을 보여줄 수 없는 경우 자동으로 스크롤을 구현한다
+ 문득 생각해보니.. primarySwatch로 적용한 색이 적용되지 않았었다는걸 깨달았다
-> 구글링을 해보니, Flutter 3.16 버전부터 기본 테마가 Meterial 3로 적용되어서 그런 것이라고 한다
useMaterial3 : false를 추가하면 적용된다
5) initState, dispose
- stateful 위젯과 별도로 state클래스를 상속받은 인스턴스(state) 객체 존재 - stateful위젯은 state객체를 생성하고, 이 객체는 플러에 의해 자신의 BuildContext를 갖게됨(즉 위젯트리에 삽입됨) - 그 이후 상태초기화 수행
- 이후 상태가 업데이트 될 때마다 state 객체의 build 메소드가 호출되면서 ui 업데이트
- state가 일시적으로 위젯트리에서 제거될 때는 deactivate 메소드가 호출되고, 영구적으로 제거될때는 dispose 메소드 호출
- 생명주기마다 그에 해당하는 메소드가 있지만, 일반적으로 initState 및 dispose 메소드를 사용하여 기능 구현할 일이 많음
- initState : 화면이 로드될 때 새로운 데이터를 받아옴, 일부 역할은 FutureBuilder로 대체가능
- dispose : 화면 사라질 때 이벤트리스너 정리
- initState 내부에선 setState 사용하지 않음 (init은 build 전에 호출되는 것 -> setState로 build 메소드 실행을 다시 요청할 필요가 없다)
- initState의 사용은 이전에 경험했듯, @override 키워드를 붙여야 함
- super.initState()를 반드시 첫줄에 작성해주어야 함(프레임워크에 미리 정의된 initState() 작업을 호출해 주어야 하기때문)
- setState 쓰지 않음 ! 라이프사이클 상 setState를 호출할 수 있는 타이밍이 아님, 또한 ui가 아직 생성되기 전이므로 여기서 수정하거나 조작한 값들은 ui에 반영됨
6) 상태 넘기기
위처럼 상태를 다른 화면으로 넘겨줄 수 있다. 그러나 이 방식의 단점은 단방향적이며, 위젯 트리가 복잡해지면 같은 상태를 조부모 위젯에서 손자 위젯 방향으로 여러번 넘겨줘야함 (프롭 드릴링)
7) 네비게이션
- push and pop 방식 많이 사용
-> 앱이 맨 처음 로드하는 화면은 고정되어 있고, 새로운 화면을 불러오게 될 때 화면 위에 화면을 하나씩 쌓는다(push) / 컴퓨터에서 일반적으로 이야기하는 stack의 원리임)
-> 뒤로 가기 버튼을 누르면, 맨 위에 쌓인 화면부터 하나씩 제거됨 (pop) -> 결국 맨 처음에 로드된 화면으로 되돌아가게 됨
- 앱바를 사용한다면, push를 구현하면 pop(뒤로가기 버튼)을 자동 구현해줌
- 6)에서의 사진을 다시 보면, push 안에 다음 화면을 바로 넣는게 아니라 머터리얼페이지라우트라는 걸 사용해서 다음 화면이 될 위젯을 지정하고 있음 : push가 위젯을 직접 집어넣는 개념이 아니라, Route라고 하는 네비게이터에서 쓰는 특수한 단위를 집어넣기 때문에
- 네비게이터는 반드시 Navigator.of(context)와 같이 사용한다 : inherited 위젯 -> context를 통해 현재 네비게이터를 호출하는 위젯이 위젯트리에서 어느 위치인지를 파악한다
8) 서버 통신
- HTTP 통신 : 하이퍼텍스트 통신 규약 -> 웹을 통해 정보를 주고 받기 이ㅜ해 쓰이는 약속
- 클라이언트가 서버에 요청을 보내면, 서버가 클라이언트의 요청에 따른 응답을 보내는 방식으로 주로 사용됨
- HTTP 요청은 자원의 위치(URI)를 정확히 지정하고, 메소드라고 불리는 행위를 지정해서 보내야 정상적으로 처리될 수 있다
- 다트를 포함한 대부분의 프로그래밍 언어, 플러터를 포함한 대부분의 프레임워크에서는 HTTP 요청에 대한 응답을 마냥 기다리지 않음 -> 사용자 인터랙션 처리 등 다른 일을 하고 있다가 응답이 오면 그때서야 그에 대한 처리를 수행함 : 비동기!
- HTTP 요청에 대한 응답 형식 : 일반 텍스트, HTML, JSON 등 -> 응답 헤더에 Content-type이 명시되어 있으므로 타입에 따라 적절하게 처리하면 된다
- 메소드 : get(서버 자원 가져옴, 요청바디 없음), post(서버의 자원 추가, 요청 바디 존재), put(서버 자원 수정 요청 바디 존재), patch(서버 자원 수정, 요청 바디 존재), delete(서버 자원 삭제) 등
- 상태코드 : http 요청에 대한 응답의 상태를 나타내는 코드 -> 2xx는 성공, 4xx는 주로 클라이언트측 오류, 5xx는 주로 서버 오류
- dart:http 라이브러리 : api 요청 및 응답 등을 쉽게 할 수 있도록 도와줌 (다트 공식 라이브러리)
- JSON이란, 텍스트 형식으로 구조화된 데이터를 표기하는 방식 -> 키와 값의 조합임
9) dart:http 라이브러리 사용 예시 : 고양이에 관한 랜덤한 정보를 제공해주는 api 사용예시
- 먼저 dart:http와 dart:conver를 임포트 한다
- 비동기로 api호출을 진행하는 함수 getData를 살펴보면, 먼저 uri 를 작성한다. uri는 url과 유사하지만 더 넓은 개념이다
- uri는 다음과 같은 순서로 작성한다 : ( 맨 앞의 https:// 생략) 도메인 -> (맨 앞의 / 생략) 세부경로 -> (map 형식) 쿼리 파라미터 => 현재는 쿼리 파라미터는 존재하지 않으므로 도메인과 세부경로를 각각 나눠서 넣어준다
- 그 다음줄인 http.get(uri)로 api 요청과 수신이 이뤄진다 -> await를 통해 응답을 기다린다
- await문 이후부터는 요청에 대한 응답을 수신한 상황임 -> 상태코드를 별도 변수로 저장한다
- JSON으로 온 응담을, Decode를 이용하여 body에 저장한다 -> 그 후 body의 text필드의 값만 꺼내서 사용한다 (고양이에 관한 랜덤한 정보)
- 그 후 build 부분 코드를 위와 같이 작성하면 완성이다
- 사진과 같이, 새로고침을 할 때마다 api에서 얻어온 고양이에 관한 사실들을 랜덤하게 보여준다
+ 구글링을 하다보니, FutureBuilder 위젯을 쓰면 Flutter에서 비동기 작업의 결과를 쉽게 처리하고 UI에 반영할 수 있는 것 같다. 다음에 써봐야지
'dev > 프론트엔드' 카테고리의 다른 글
SeQR 개발일지 (0) | 2024.09.25 |
---|---|
flutter : 앱 개발 과정 빠르게 훑어보기 (0) | 2024.09.22 |
코드팩토리 flutter : 3장 chap 8 (0) | 2024.09.18 |
코드팩토리 flutter - 2장 chap 6 (0) | 2024.09.18 |
코드팩토리 flutter : 2장 - chap 4,5 (0) | 2024.09.16 |