Flutter는 네이티브 크로스 플랫폼 애플리케이션을 위한 Google의 UI 프레임워크입니다. Flutter Docs (2025)에 따르면, Flutter는 Google Play에서 500,000개 이상의 앱에 사용됩니다. Widget, StatefulWidget, BuildContext 및 렌더링 트리 이해는 Flutter 개발의 기초입니다.
핵심 요점
Widget — UI 일부의 선언적 설명. Flutter의 모든 것은 Widget입니다: 버튼부터 앱 자체까지. Widget은 구성입니다(UI 자체가 아님). StatelessWidget — 불변 Widget. build()는 한 번 호출됩니다. 상태가 없습니다. 정적 콘텐츠에 사용됩니다. StatefulWidget — 가변 Widget. 변경 가능한 State 객체를 가집니다. setState() — 재구축을 트리거합니다. State — StatefulWidget에 연결된 가변 객체. 변경될 수 있는 데이터를 포함합니다.
StatelessWidget — build()는 한 번 호출됩니다. 헤더, 아이콘, 정적 텍스트에 적합합니다. StatefulWidget — build()는 setState()가 호출될 때마다 호출됩니다. 양식, 변경 목록, 타이머에 적합합니다. InheritedWidget — 생성자를 통한 명시적 전달 없이 데이터를 트리 아래로 전달. Theme, MediaQuery, Navigator — InheritedWidgets입니다. BuildContext — 트리에서 Widget의 위치. context.of<T>, context.watch<T>, context.select<T,R> — InheritedWidget 접근.
// Flutter Widget 예시: setState를 사용하는 StatefulWidget
class CounterWidget extends StatefulWidget {
const CounterWidget({Key? key}) : super(key: key);
@override
State<CounterWidget> createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _counter = 0;
void _increment() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Flutter Counter')),
body: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('You have pushed the button:'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _increment,
child: const Icon(Icons.add),
),
);
}
}Widget — 구성. StatelessWidget — 불변. StatefulWidget — setState()로 가변. IT Sectr는 StatelessWidget으로 시작하고 상태가 필요할 때만 StatefulWidget으로 전환할 것을 권장합니다.
Flutter는 효율적인 렌더링을 위해 세 가지 트리를 사용합니다. Widget Tree — 구성 트리. Widget은 자주 생성됩니다(매 build마다), 가볍습니다. Element Tree — 요소 트리. Widget당 하나의 요소(유형이 변경되지 않는 경우). Element — Widget과 RenderObject 간의 브리지. RenderObject Tree — 렌더링 트리. 크기, 위치, 그리기를 처리합니다. RenderObject — 무겁고, 드물게 생성됩니다. Flutter는 Widget Tree를 비교하고 Element Tree를 업데이트하여 RenderObject Tree 업데이트를 트리거합니다.
Key — Element Tree에서 Widget 식별자. ValueKey, ObjectKey, UniqueKey, PageStorageKey. Key를 통해 Flutter는 재구축 시 이전 Widget과 새 Widget을 일치시킬 수 있습니다. Key가 없으면 Flutter는 Widget 유형과 위치로 일치시킵니다. GlobalKey — 다른 Widget에서 State에 접근. 용도: 복잡한 양식, 애니메이션, 테스트에서 State 접근. IT Sectr는 목록(List.generate)에 Key를 사용하고 불필요한 GlobalKey는 피할 것을 권장합니다.
Expanded — Row/Column/Flex에서 사용 가능한 공간을 채우는 Widget. Flexible — 채우기를 강제하지 않음(더 작을 수 있음). MediaQuery — 기기 정보가 포함된 InheritedWidget: 화면 크기, 방향, 플랫폼, 텍스트 스케일 팩터. Theme/ThemeData — 중앙 집중식 테마. Theme.of(context) — 접근. MaterialApp — 라우팅, 테마, 로케일 구성을 위한 루트 Widget. Scaffold — AppBar, Drawer, BottomNavigationBar가 포함된 기본 레이아웃. AppBar — 상단 패널.
Navigator — 경로 스택(Routes). Navigator.push — 화면 열기(Future 반환). Navigator.pop — 닫기(결과 포함). MaterialPageRoute — 애니메이션 전환(오른쪽에서 슬라이드). Named Routes — 문자열 식별자. onGenerateRoute — 중앙 집중식 핸들러. Navigator 2.0(Router + RouteInformationParser + RouterDelegate) — 웹, 딥 링크 및 복잡한 시나리오를 위한 선언적 네비게이션.
Navigator 2.0 — 선언적 네비게이션. Router — 중앙 Widget. RouteInformationParser — URL 파싱. RouterDelegate — 스택 관리. GoRouter(패키지) — Navigator 2.0의 단순화된 래퍼. 지원: 명명된 경로, 매개변수, 리디렉션, 딥 링크. IT Sectr는 대부분의 프로젝트에 GoRouter를, 복잡한 시나리오(웹, 데스크톱)에만 Navigator 2.0을 권장합니다.
FutureBuilder — Future를 기반으로 UI를 구축하는 Widget. connectionState: none, waiting, active, done. 용도: HTTP 요청, DB 읽기, 타이머. StreamBuilder — Stream용 Widget(무한 데이터 흐름). snapshot.data, snapshot.hasError, snapshot.hasData. 용도: WebSocket, Firebase, 위치 업데이트. 두 Widget 모두 새 데이터 수신 시 재구축됩니다.
Provider — 간단한 DI + 상태 관리. ChangeNotifierProvider, MultiProvider. Riverpod — Provider의 현대적 대체: 컴파일 안전, BuildContext에 독립적. Bloc — 이벤트 기반 아키텍처: Cubit(단순 이벤트) vs Bloc(복잡). GetX — 경량 상태 관리 + DI + 라우팅. setState — 가장 간단함, 로컬 상태용. IT Sectr는 새 프로젝트에 Riverpod, 기존 프로젝트에 Provider를 권장합니다.
MediaQuery — 화면 크기, 방향, 플랫폼, textScaleFactor. MediaQuery.of(context).size.width. ThemeData — 앱 테마: 색상, 글꼴, 모양. Theme.of(context).textTheme.bodyLarge. Hot Reload — 실행 중인 앱에 코드 주입. 상태 유지. 지원하지 않음: main() 변경, 전역 변수, 정적 필드. Hot Restart — 전체 앱 재시작(상태 손실). Hot Reload — Flutter의 개발자를 위한 주요 이점.
| Widget 유형 | 설명 | 예시 |
|---|---|---|
| StatelessWidget | 불변, build 한 번 | Text, Icon, Padding, Center |
| StatefulWidget | 가변, setState 재구축 | TextField, Checkbox, AnimationController |
| InheritedWidget | 데이터를 아래로 전달 | Theme, MediaQuery, Navigator |
| ProxyWidget | 다른 Widget용 래퍼 | ParentDataWidget (Positioned, Expanded) |
| RenderObjectWidget | RenderObject 생성 | Column, Row, Stack(사용자 정의) |
StatelessWidget — 정적 콘텐츠용. StatefulWidget — 동적 콘텐츠용. InheritedWidget — DI용. IT Sectr는 기본적으로 StatelessWidget을, 필요한 경우에만 StatefulWidget을 권장합니다.
LayoutBuilder — 부모 치수에 적응. OrientationBuilder — 방향에 적응. Expanded vs Flexible — Row/Column에서 공간 분배. MediaQuery — 태블릿 및 데스크톱용 중단점. SafeArea — 시스템 요소(노치, 상태 표시줄)로부터 여백. AspectRatio — 비율 유지. IT Sectr는 적응형 레이아웃에 LayoutBuilder, 가로 방향에 OrientationBuilder를 권장합니다.
단위 테스트 — 비즈니스 로직, 리포지토리, 모델 테스트. dart test — 실행. Widget 테스트 — 격리된 Widget 테스트. WidgetTester — pumpWidget, tap, enterText. 통합 테스트 — 실제 기기/에뮬레이터에서 전체 시나리오. Mockito — 의존성 모킹. Golden 테스트 — 스크린샷 비교(golden 파일). IT Sectr는 각 화면에 Widget 테스트, 비즈니스 로직에 단위 테스트를 권장합니다.
void main() {
testWidgets('Counter increments on tap', (tester) async {
await tester.pumpWidget(const MaterialApp(home: CounterWidget()));
expect(find.text('0'), findsOneWidget);
await tester.tap(find.byType(FloatingActionButton));
await tester.pump();
expect(find.text('1'), findsOneWidget);
});
}암시적 애니메이션 — AnimatedContainer, AnimatedOpacity, AnimatedPadding, TweenAnimationBuilder. 속성 변경이 자동으로 애니메이션됩니다. 명시적 애니메이션 — Tween이 있는 AnimationController. forward() / reverse(). Hero 애니메이션 — 태그가 있는 Hero Widget — 화면 간 전환 애니메이션. Staggered 애니메이션 — Interval을 사용한 애니메이션 체인. Lottie — After Effects 애니메이션 통합. Rive — 대화형 애니메이션(state machine). IT Sectr는 80%의 경우 AnimatedContainer를, 복잡한 시나리오에는 AnimationController를 권장합니다.
class AnimatedBox extends StatefulWidget {
@override
State<AnimatedBox> createState() => _AnimatedBoxState();
}
class _AnimatedBoxState extends State<AnimatedBox> {
bool _expanded = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => setState(() => _expanded = !_expanded),
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
width: _expanded ? 200 : 100,
height: _expanded ? 200 : 100,
color: _expanded ? Colors.blue : Colors.red,
child: const Center(child: Text('Tap me')),
),
);
}
}http — 간단한 HTTP 클라이언트(get, post, put, delete). dio — 인터셉터, 타임아웃, 재시도, 로깅이 포함된 고급 클라이언트. graphql_flutter — Flutter용 GraphQL 클라이언트. json_serializable — 어노테이션을 통한 fromJson/toJson 생성. Retrofit Dart — Retrofit과 같은 type-safe HTTP 클라이언트. WebSocket — web_socket_channel을 통해. Firebase — Cloud Firestore, Realtime Database, Cloud Functions. IT Sectr는 REST API에 dio, GraphQL에 graphql_flutter를 권장합니다.
Flutter DevTools — 도구 세트: Inspector(Widget 트리), Timeline(성능), Memory, Network, Logging. Profile mode — 디버그 없이 프로파일링. Performance overlay — FPS, 빌드 시간. Flame chart — 플레임 차트 트레이싱. DevTools — 프로덕션에서 Flutter 애플리케이션 최적화를 위한 필수 도구.
Flutter Web — Flutter를 WASM(WebAssembly)으로 컴파일. CanvasKit(Skia) vs HTML renderer. CanvasKit — 픽셀 완벽但 더 무거움. HTML renderer — 가벼움但 제한 있음. WASM(Flutter 3.22+) — 네이티브 성능. LayoutBuilder 및 MediaQuery를 통한 반응형 적응. IT Sectr는 데스크톱 웹 애플리케이션에 CanvasKit, 콘텐츠 사이트에 HTML renderer를 권장합니다.
자주 묻는 질문
StatelessWidget — 불변, build 한 번. StatefulWidget — 가변 State 및 setState() 포함.
Widget Tree — 구성. Element Tree — 브리지. RenderObject Tree — 렌더링(크기, 그리기).
BuildContext — 트리에서 Widget 위치. InheritedWidget — 데이터를 아래로 전달(Theme, MediaQuery).
Navigator — 화면 스택. push() → pop(). Named Routes — 문자열 이름. Navigator 2.0 — 선언적.
Hot Reload — 1-2초 내 코드 주입, 상태 보존. Hot Restart — 전체 재시작.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.