Flutter
# Google I/O 플러터 세션 모음
# Brian / Mia / Jay Flutter 회의록
# 2023/05/11
[ 제이 회의록 작성 ]
- 제이/미아 -> 브라이언 : 플러터 공부하면서 웹 QA 진행할 것 같다고 전달드림
- 톰 -> 브라이언 : 웹 피쳐 개발은 없을 것 같다.
- 플러터 관련 브라이언 강의(?)
- 앞으로 생기는 페이지는 플러터로 구성되어야 할 것 같다.
- 플러터는 인증 토큰 관련 이슈가 발생할 것 같다.
- 플러터 Doc 관련
- 데이터 처리와 같이 무거운 연산은 백엔드에서 담당을 하고 프론트는 받아서 최고의 ux를 제공하는 것이 목표
- 플러터에서 제일 중요한 것은 위젯, 모든 것이 위젯 클래스에서 상속받아 구성된다. 화면에 그려지는 하나 하나가 모두 위젯.
- 스캐폴드라는 컨셉을 요새 많이 사용한다. build나 child도 위젯, 스케폴드는 템플릿을 제공해준다. 예를 들어 스케폴드의 인자로 drawer: Drawer()를 통해 drawer도 손 쉽게 넣을 수 있다.
- 클래스도 위젯이다. build를 통해 스테이트풀, 스테이트리스 위젯을 리턴한다.
- 스테이트매니지먼트에서 가장 기본적인 것은 setState를 사용하는 것이다.
- 스테이트풀 위젯은 값이 바뀌는 위젯이다. 변수들의 값이 바뀌는 것을 감지한다 이 때 setState를 사용한다. (ex setState(() => count++))
- 체인지노티파이는 스테이트매니지먼트를 하는 방법 중 하나이다. 사람들이 스테이트매니지먼트를 편하게 쓰기 위해 프레임워크들을 많이 넣어두었는데 provider라는 것이 있는데 이것을 사용하는 것이다. setState를 해서 상태 업데이트를 하는 것이 아닌 context.watch를 통해 특정 값을 구독하고 그 값을 받아서 사용할 수 있다.
- 스테이트풀안에서 하나의 변수가 변경되면 소속된 변수 모두 다시 렌더한다. 이 부분에서 리소스 낭비, 성능저하가 발생할 수 있다. 스테이트매니지먼트가 이런 문제가 발생하기도 한다. 그래서 사용하는 것이 context.watch이다. context.watch()로 구독해서 사용하는 경우 비지니스 로직에서 주는 데이터를 그리기만 할 수 있다. 비지니스 로직 클래스를 따로 분리하고 context.watch가 포함된 뷰 클래스를 따로 사용하여 렌더링 성능을 향상 시킬 수 있다. (아키텍처와 관련된 듯) 이렇게 변수를 클래스 내부에서 직접적으로 사용하지 않고 구독해서 사용하는 방식이 provider 사용 방식!
- 프로바이더를 사용하기에 따라 또 달라질 수 있다. Depth 10에 위젯 클래스가 있다고 했을 때 Depth 5에 프로바이더가 적용되어있다고 하면 나머지 5는 상태가 변경될 때 마다 렌더링되는 이슈가 발생할 수 있다. 그러므로 잘 생각해서 구현해야한다.
- 비지니스 로직 / 뷰를 분리한 뒤에 뷰를 목데이터를 사용하여 빠르게 짜고 백엔드에서 데이터 연산을 처리한 뒤 비지니스 로직에 적용시키고 상태 변화가 필요한 부분에는 context.watch를 사용하는 것이 플러터 로직의 구성
- [미아 질문] 인자를 모르는 상태에서 인자를 찾아볼 수 있는 노하우?
- [ 브라이언 답변 ]
- 플러터 스캐폴드는 매터리얼 디자인을 사용한다. 관련 파라미터들(ex action)은 메터리얼 디자인 홈페이지에 들어가면 확인할 수 있지만 너무나 많기 떄문에 파악하는 것이 쉽지 않다. 플러터 공식 유튜브 계정에 가면 위젯 사용법과 해당 위젯에 대표적인 파라미터 등을 설명해주는 영상이 있다. 이 영상들을 확인하면 기본적으로 사용할 수 있는 파라미터들을 확인할 수 있다. 한번 둘러보는 것을 추천! 그 후 없으면 공식 Docs, 그래도 없으면 검색 등을 통해 찾아야한다.
- 매치아크 로비를 기준으로 설명하면 로비 전체는 스캐폴드로 감싸게 되고, 로비 전체에 대충 위젯 7개, 슬라이드는 플러터의 페이지 뷰(보통 캐러셀) 사용 -> 이 때 양 쪽 화살표는 스택등을 사용해서 레이어가 겹치게 해서 구성할 수 있다. 매치아크나우는 리스트타일을 통해 통째로 구현할 수 있다. 1,2,3으로 나눠서 3에서 반으로 쪼개면 된다. 또 동일한 구성에 대해서는 컴포넌트 재활용을 통해 사용할 수 있다.
- 범용적으로 갭을 주는 방법도 있다. 예를 들어 ListView를 사용한다고 했을 때 ListView.separator 등을 사용할 수 있다.
- 공식문서에서 샘플이 없는 클래스의 경우 하위 클래스(혹은 인자)일 수 있다.
- 모바일은 기기마다 사이즈가 다른데 한 코드로 어떻게 모든 기기에 대응할 수 있을 지 고민해봐야한다. 안드로이드는 너무나 기기 사이즈가 파편화 되어있다. 이런 경우 대부분 기기 사이즈를 얻어 나누고 곱하는 등의 연산을 하는데 이러지 말고 Expanded와 같은 위젯을 사용할 수 있다.
- [ 제이 질문 ] 플러터의 편리한 예시는 많이 보았는데 혹시 플러터로 구현하기 어려운 UI가 무엇이 있을까요? 플러터의 단점도 궁금해서 여쭤봅니다. 그런건 딱히 없을까용?
- [ 브라이언 답변 ]
- 예를 들어 ios에서 지원하는 것이 플러터에서 없다고 하면 메소드채널로 래핑해서 불러서 쓰면 된다. 플러터에서 아직 지원을 안하는 것일 뿐이다. 결론적으로 구현하기 어려운 부분은 일단 매치아크 서비스에서는 없으며 구현하기 불가능한 UI도 거의 없다고 보여진다.
- 플러터로 구현한 사이트들 : https://itsallwidgets.com/
- [미아 질문] 웹에서 다음 피쳐가 피드였는데 피드 구현 시 인피니트 스크롤, 윈도우윙가 필요했었다. 다트에서는 이런 상황을 어떻게 처리해야할지?
- [ 브라이언 답변 ]
- 기본적으로 리스트뷰를 활용하여 외부 패키지를 사용하지 않아도 사용할 수 있다.
- 페이지네이션의 경우 리스트뷰에다가 기본적으로 초기 데이터 깔고 리스너(스크롤 끝까지 확인하는지 확인하는 용도)를 붙여 스크롤이 끝에 도달할 경우 데이터를 업데이트 시키는 방향으로 진행한다.
- 컴퓨팅 사이언스와 관련된 내용인데 예를 들어 피드가 1000개가 있다고 가정했을 때 이미지 1000개를 메모리에 들고 있는 것이 아닌 화면에 보여지는 이미지만 메모리에 들고 있다고 보면 된다. 쉽게 말해 뷰에 띄워줄 이미지와 뷰에 띄워지지 않을 이미지의 메모리 처리가 다르게 이루어진다. 요즘 렌더링엔진(UI엔진)들이 대부분 이렇게 동작한다. 결론은 1000개의 피드를 띄운다고 했을 때 텍스트나 URL링크는 메모리에 들고 있으며 이미지는 메모리에 직접 1000개 전부 가지고 있지 않은 것이다.
- [ 미아 질문 ] 위젯 트리 Depth가 상당히 깊어질 것 같은데 해당 부분에 대해 더욱 학습하고 싶다.
- [ 브라이언 답변 ]이미 최적화가 잘 되어있고 프로바이더를 사용하기에 따라 최적화가 잘 이루어질 수 있다.
- [ 미아 재질문 ] 코드단 관련해서 질문드린 것이다.
- [ 브라이언 답변 ] 재활용을 얼마나 할 수 있냐에 따라 뎁스는 자연스럽게 줄어들 수 있다.
- builder()를 사용한다는 것은 동적인 데이터를 사용한다는 것이다.
- Stack은 레이어를 쌓을 때 사용한다.
- 실제 렌더링은 runApp()에서 시작된다. 매치아크 플러터 외주 코드를 기준으로 얘기하면 runMatcharkApp 클래스안에서 다양한 api들이 runApp()전에 트리거되는데 이런 부분들에 대해서도 당장 필요하지 않다면 runApp()이 실행된 이후 필요한 상황에 요청할 수 있도록 하는 것을 고민해보아야한다.
- Next Step
- [x] 공식 문서 ‘New to Flutter?’
- [x] 외주 코드 중 pubspec.yaml 안에 패키지들에 대해 알아보기
- 학습을 빨리 마무리하고 외주 코드 보면서 돌려보는 것이 우선적일 것 같다. 그러므로 외주 코드 일단 빨리 둘러보아라!
- 브라이언은 피드 구현하는 것에 대해 생각 or 구현해보신다고 하심. 슬랙으로 소통하기로 함.
[ 미아 회의록 작성 ]
- Q : class 형 variable 을 정의할 때 ClassName variableName 형식을 띄는데,(ex. IconData icon) 변수 정의할 때 void 대신에 type assertion 으로 정의하는 건가
- Q : notifyListeners vs setState
- 직관적 예상: notifyListeners는 MyApp 내에서 전역 state 변경 noti이고, setState 는 위젯내부 state 변경 noti인가?
- A. setState는 StatefulWidget 안에서 쓸 수 있는게 맞다. 다만,setState가 트리거 되면 그 상태가 포함된 위젯 전체가 리렌더링 된다. notifyListeners는 context notify, watch 로 관리한다. 이때 watch 하는 부분만 리렌더링 되므로, 비용이 적다.
- Q : Padding을 부모 위젯으로 잡고 child를 포함하다니.. 낯설다 그리고 Padding 파라미터 멤버에는 children[] 가 없다(쓸수없다)..! 호버했을떄 뜨는 가이드 따라 basic.dart 탐색해보니 SingleChildRenderObjectWidget 는 child로 단일 요소를 자식으로 갖는 것 같다.
- Q : 복잡한, depth가 깊은 위젯(컴포넌트)는 child 트리가 엄청 깊어질것같은데, 컴포넌트 디자인 모델전략을 어떻게 취하는지 궁금하다. 우리 서비스에서는 불가피하게 현재 외주팀에서 짜놓은 것 바탕으로 해야겠지만 ..
- A : 프로젝트 파일구조는 재활용