
4.1 위젯(Widgets) - 확장 가이드
개요
Flutter에서 위젯(Widgets)은 UI 구성 요소의 기본 단위로, 앱의 모든 시각적 요소를 구성하는 불변(immutable) 객체이다12. “Everything is a widget”이라는 Flutter의 핵심 철학에 따라, 텍스트, 버튼, 레이아웃, 애니메이션까지 모든 UI 요소가 위젯으로 표현된다32.
위젯의 핵심 특성
불변성(Immutability)
모든 위젯은 불변 객체로, 한 번 생성되면 수정할 수 없다14. 상태가 변경될 때는 기존 위젯을 폐기하고 새로운 위젯 인스턴스를 생성하여 위젯 트리를 재구성한다15.
위젯 트리 구조
위젯들은 계층적 트리 구조를 형성하며, 부모-자식 관계를 통해 복잡한 UI를 구성한다52. 각 위젯은 build()
메서드를 통해 자신의 하위 위젯들을 정의한다16.
StatelessWidget vs StatefulWidget
구분 | StatelessWidget | StatefulWidget |
---|---|---|
상태 변경 | 불가능 - 생성 후 고정78 | 가능 - setState() 호출로 재렌더링97 |
생명주기 | build() 한 번만 호출610 | 복잡한 생명주기 단계 존재911 |
성능 | 가벼움, 빠른 렌더링812 | 상대적으로 무거움712 |
사용 사례 | 정적 UI(텍스트, 아이콘)813 | 동적 UI(폼, 카운터, 애니메이션)814 |
구조 | 단일 클래스144 | 위젯 클래스 + State 클래스144 |
StatelessWidget 특징
- 정적 UI 요소에 최적화된 위젯으로, 내부 상태를 갖지 않는다713
- 부모 위젯으로부터 전달받은 데이터가 변경되면 자동으로 재빌드된다64
- 생성자와
build()
메서드만으로 구성되는 간단한 구조610
StatefulWidget 생명주기
StatefulWidget은 다음과 같은 복잡한 생명주기를 갖는다91511:
- Constructor → createState() → initState() → didChangeDependencies() → build()
- 상태 변경 시: setState() → build() 재호출916
- 업데이트 시: didUpdateWidget() → build()166
- 소멸 시: deactivate() → dispose()1615
위젯 성능 최적화
불필요한 재빌드 방지
- StatelessWidget 우선 사용: 가능한 경우 StatelessWidget을 선택하여 성능 향상1217
- 위젯 분할: 큰 위젯을 작은 단위로 나누어 필요한 부분만 재빌드1217
- const 생성자 활용: 컴파일 타임에 결정되는 위젯은
const
로 선언하여 메모리 최적화18
상태 관리 최적화
- setState() 범위 최소화: 변경이 필요한 최소 범위에서만
setState()
호출1917 - Provider, Riverpod, Bloc 등 상태 관리 라이브러리 활용으로 전역 상태 효율적 관리1920
렌더링 파이프라인과 위젯
Flutter의 렌더링 파이프라인에서 위젯은 다음 과정을 거친다2122:
- 위젯 트리 생성: 사용자 입력이나 상태 변경 시 위젯 계층 구조 생성
- Element 트리 변환: 위젯을 Element 객체로 변환하여 상태 관리
- RenderObject 생성: 실제 레이아웃과 페인팅을 담당하는 렌더 객체 생성
- Layer 트리 구성: GPU 렌더링을 위한 레이어 구조 생성
- GPU 래스터화: 최종적으로 화면에 픽셀로 렌더링2123
커스텀 위젯 개발
커스텀 위젯의 이점
커스텀 위젯 생성 과정
- 요구사항 정의: 위젯의 목적과 기능 명확화2427
- StatelessWidget/StatefulWidget 선택: 상태 필요 여부에 따라 결정2428
- 생성자 매개변수 설계: 외부에서 전달받을 속성들 정의2628
- build() 메서드 구현: 실제 UI 구조 반환2827
- 테스트 및 최적화: 다양한 시나리오에서 동작 검증2427
위젯 카탈로그와 활용
Flutter는 풍부한 기본 위젯 라이브러리를 제공한다329:
기본 위젯 카테고리
- 레이아웃: Container, Row, Column, Stack, Flex3031
- 텍스트: Text, RichText2930
- 입력: TextField, Button, Checkbox2931
- 내비게이션: AppBar, Drawer, BottomNavigationBar31
- 스크롤: ListView, GridView, SingleChildScrollView2931
Material & Cupertino 디자인 시스템
핵심 권장사항: 위젯 선택 시 성능과 유지보수성을 고려하여 StatelessWidget을 우선 사용하고, 상태 관리가 필요한 경우에만 StatefulWidget을 활용한다. 복잡한 UI는 작은 위젯으로 분할하여 재사용성과 가독성을 높이며, 커스텀 위젯 개발을 통해 일관된 디자인 시스템을 구축할 것을 권장한다.
Footnotes
-
https://docs.flutter.dev/get-started/fundamentals/widgets ↩ ↩2 ↩3
-
https://www.f22labs.com/blogs/what-is-flutter-widget-tree-a-comprehensive-guide/ ↩ ↩2
-
https://ifhead.tistory.com/entry/Flutter-Stateless-Widget과-Stateful-Widget-차이-생명주기 ↩ ↩2 ↩3 ↩4
-
https://parkjh7764.tistory.com/entry/Flutter-위젯-라이프사이클-StatelessWidget-StatefulWidget-LifeCycle-함수-메서드-정리 ↩ ↩2
-
https://jaceshim.github.io/2019/01/28/flutter-study-stateful-widget-lifecycle/ ↩ ↩2
-
https://somniosoftware.com/blog/13-best-practices-for-flutter-performance-optimization ↩ ↩2 ↩3 ↩4
-
https://hyeonsdevlog.tistory.com/entry/Flutter-lifecycle-플러터-생명주기 ↩ ↩2
-
https://ayoung0073.tistory.com/entry/flutter-app-lifecycle ↩ ↩2 ↩3
-
https://docs.flutter.dev/get-started/fundamentals/state-management ↩ ↩2
-
https://docs.flutter.dev/data-and-backend/state-mgmt/simple ↩
-
https://theprogrammingway.com/flutters-rendering-pipeline/ ↩ ↩2
-
https://velog.io/@tygerhwang/Flutter-렌더링-원리와-과정-화면은-이렇게-그려진다 ↩
-
https://www.techaheadcorp.com/blog/creating-custom-widgets-flutter-extending-functionality/ ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
https://www.freecodecamp.org/news/how-to-build-a-custom-widget-in-flutter/ ↩ ↩2
-
https://www.geeksforgeeks.org/flutter/flutter-custom-widgets/ ↩ ↩2
-
https://www.dhiwise.com/post/how-to-achieve-optimal-code-efficiency-with-custom-widget ↩ ↩2 ↩3
-
https://dev.to/harsh8088/building-a-custom-flutter-widget-from-scratch-335i ↩ ↩2 ↩3
-
https://www.getwidget.dev/blog/top-flutter-widgets-catalog/ ↩ ↩2 ↩3 ↩4