Flutter 튜토리얼 73편: Widget Inspector
요약
핵심 요지
- 문제 정의: 복잡한 위젯 트리에서 특정 위젯을 찾거나 레이아웃 문제의 원인을 파악하기 어렵다.
- 핵심 주장: Widget Inspector1는 위젯 트리를 시각적으로 탐색하고 각 위젯의 속성과 제약 조건을 확인할 수 있게 한다.
- 주요 근거: 실행 중인 앱에서 위젯을 직접 선택하고, 레이아웃 익스플로러로 Flex 레이아웃을 분석할 수 있다.
- 실무 기준: UI 문제가 발생하면 먼저 Widget Inspector로 위젯 트리와 제약 조건을 확인해야 한다.
- 한계: 너무 복잡한 위젯 트리는 탐색이 어려우며, 렌더링 성능 문제는 Performance 탭을 사용해야 한다.
문서가 설명하는 범위
- Widget Inspector 인터페이스 이해
- 위젯 트리 탐색 및 검색
- 레이아웃 익스플로러 사용법
- 디버깅 시각화 옵션
읽는 시간: 15분 | 난이도: 초급
참고 자료
- Using the Flutter inspector - Widget Inspector 공식 문서
문제 상황
Flutter 앱을 개발하다 보면 UI가 예상대로 표시되지 않는 상황을 자주 만납니다. 오버플로우 에러, 위젯이 보이지 않는 문제, 레이아웃이 깨지는 문제 등이 있습니다.
UI 디버깅의 어려움
문제: Row에 있는 Text가 잘려요├─ 코드만 봐서는 원인을 알기 어려움├─ 위젯 중첩이 깊으면 추적이 힘듦└─ Constraints가 어디서 결정되는지 모름문제는 다음과 같습니다.
- 위젯 트리가 깊으면 어떤 위젯이 문제인지 찾기 어렵습니다.
- 제약 조건(Constraints)2이 어떻게 전파되는지 코드만으로는 파악하기 어렵습니다.
- 오버플로우가 발생해도 정확한 원인 위젯을 특정하기 어렵습니다.
해결 방법
Widget Inspector를 사용하면 실행 중인 앱의 위젯 트리를 시각적으로 탐색하고, 각 위젯의 속성과 제약 조건을 확인할 수 있습니다.
챕터 1: Widget Inspector 인터페이스
Why
NOTEWidget Inspector는 코드와 실제 렌더링 결과를 연결해 줍니다. 화면에 보이는 요소가 어떤 위젯인지, 그 위젯의 속성은 무엇인지 바로 확인할 수 있습니다.
복잡한 레이아웃 문제를 해결할 때 가장 먼저 사용해야 하는 도구입니다.
What
NOTEWidget Inspector는 세 가지 주요 영역으로 구성됩니다.
┌───────────────────────────────────────────────────────────────┐│ 툴바: [Select] [Refresh] [Slow Animations] [Paint Baselines] │├─────────────────────────────┬─────────────────────────────────┤│ │ ││ 위젯 트리 │ 위젯 상세 정보 ││ (Widget Tree) │ (Widget Details) ││ │ ││ ▼ MyApp │ Type: Container ││ ▼ MaterialApp │ Size: 200.0 x 100.0 ││ ▼ Scaffold │ ││ ▼ AppBar │ Properties: ││ ▼ Body │ color: blue ││ ▼ Center │ padding: EdgeInsets.all(8) ││ Container ◀───── │ ││ │ Constraints: ││ │ BoxConstraints(0.0<=w<=... ││ │ │└─────────────────────────────┴─────────────────────────────────┘
영역 설명 툴바 위젯 선택, 새로고침, 시각화 옵션 위젯 트리 앱의 위젯 계층 구조 위젯 상세 정보 선택한 위젯의 속성, 크기, 제약 조건
How
TIPWidget Inspector 열기
- 앱을 디버그 모드로 실행합니다.
- DevTools를 엽니다.
- “Flutter Inspector” 탭을 선택합니다.
위젯 트리 탐색하기
위젯 트리에서 위젯을 클릭하면 해당 위젯의 상세 정보가 오른쪽 패널에 표시됩니다.
▼ Scaffold▶ AppBar (접힘)▼ Center (펼침)▼ ContainerText
▼: 하위 위젯이 펼쳐진 상태▶: 하위 위젯이 접힌 상태위젯 검색하기
트리 상단의 검색창에서 위젯 이름을 검색할 수 있습니다.
검색: "Container"결과: 3개의 Container 위젯 발견앱에서 직접 위젯 선택하기
툴바의 “Select Widget Mode” 버튼을 클릭하면 앱 화면에서 직접 위젯을 선택할 수 있습니다.
- “Select Widget Mode” 버튼(포인터 아이콘)을 클릭합니다.
- 앱 화면에서 분석하고 싶은 UI 요소를 탭합니다.
- 해당 위젯이 트리에서 강조되고 상세 정보가 표시됩니다.
코드로 이동하기
위젯 트리에서 위젯을 더블클릭하면 해당 위젯이 정의된 소스 코드로 이동합니다.
Watch out
WARNINGWidget Inspector 사용 시 주의사항입니다.
트리와 코드의 차이:
- 위젯 트리는 실제 렌더링되는 모든 위젯을 보여줍니다.
- 코드에서 작성한 위젯 외에도 내부적으로 생성되는 위젯이 많습니다.
// 코드에서는 간단해 보이지만Text('Hello')// 위젯 트리에서는 여러 위젯으로 구성됨// Text > RichText > RawText > ...성능 영향:
- Widget Inspector가 열려 있으면 앱 성능에 약간의 영향을 줄 수 있습니다.
- 성능 측정 시에는 Inspector를 닫는 것이 좋습니다.
결론: Widget Inspector로 위젯 트리를 시각적으로 탐색하고 문제를 빠르게 찾을 수 있습니다.
챕터 2: 레이아웃 익스플로러 사용하기
Why
NOTERow, Column, Flex 같은 레이아웃 위젯은 여러 속성이 상호작용하며 복잡한 레이아웃을 만듭니다. 레이아웃 익스플로러3는 이러한 Flex 기반 레이아웃을 시각적으로 분석합니다.
코드에서 mainAxisAlignment, crossAxisAlignment 같은 속성을 바꿔가며 테스트하지 않아도 됩니다.
What
NOTE레이아웃 익스플로러는 Flex 위젯(Row, Column, Flex)을 선택했을 때 나타납니다.
graph TD A[Flex 위젯 선택] --> B[레이아웃 익스플로러 활성화] B --> C[축 시각화] B --> D[자식 위젯 배치] B --> E[속성 조절 UI]
표시 정보 설명 Main Axis 주 축 방향 및 정렬 Cross Axis 교차 축 방향 및 정렬 자식 크기 각 자식의 실제 크기 Flex Factor Expanded/Flexible의 flex 값 여백 공간 남는 공간 표시
How
TIP레이아웃 익스플로러 사용하기
- Widget Inspector에서 Row, Column, 또는 Flex 위젯을 선택합니다.
- 상세 정보 패널에서 “Layout Explorer” 섹션을 확인합니다.
┌──────────────────────────────────────┐│ Layout Explorer │├──────────────────────────────────────┤│ ││ Main Axis: horizontal → ││ [start] [center] [end] [spaceBetween]││ ││ ┌────┐ ┌────────┐ ┌────┐ ││ │ A │ │ B │ │ C │ ││ │50px│ │ flex:2 │ │50px│ ││ └────┘ └────────┘ └────┘ ││ ││ Cross Axis: stretch ││ [start] [center] [end] [stretch] ││ │└──────────────────────────────────────┘실시간 속성 변경
레이아웃 익스플로러에서 정렬 옵션을 클릭하면 앱에 바로 반영됩니다.
예를 들어 Row의 mainAxisAlignment를 변경하려면:
- Row 위젯을 선택합니다.
- Layout Explorer에서 “spaceBetween”을 클릭합니다.
- 앱 화면에서 즉시 변경을 확인합니다.
- 원하는 설정을 찾으면 코드에 적용합니다.
Flex 요소 분석
Row(children: [Container(width: 50, color: Colors.red),Expanded(flex: 2,child: Container(color: Colors.blue),),Expanded(flex: 1,child: Container(color: Colors.green),),],)레이아웃 익스플로러에서 표시되는 정보:
자식 타입 Flex 실제 크기 Container 고정 크기 - 50px Container Expanded 2 200px Container Expanded 1 100px 오버플로우 문제 분석
오버플로우가 발생하면 레이아웃 익스플로러에서 원인을 파악할 수 있습니다.
// 오버플로우 발생 예시Row(children: [Container(width: 200),Container(width: 200),Container(width: 200), // 화면 너비 초과],)레이아웃 익스플로러에서:
- 각 자식의 크기 합계와 사용 가능한 공간을 비교합니다.
- 오버플로우된 픽셀 수가 표시됩니다.
- Expanded 또는 Flexible로 변경할 위젯을 파악합니다.
Watch out
WARNING레이아웃 익스플로러의 한계입니다.
지원 위젯:
- Row, Column, Flex 위젯에서만 동작합니다.
- Stack, GridView, CustomMultiChildLayout 등은 지원하지 않습니다.
실시간 변경의 한계:
- Inspector에서 변경한 값은 앱에 즉시 반영되지만 코드에는 반영되지 않습니다.
- 원하는 설정을 찾으면 코드에 직접 적용해야 합니다.
// Inspector에서 찾은 설정을 코드에 적용Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, // 직접 추가children: [...],)
결론: 레이아웃 익스플로러로 Flex 레이아웃 문제를 시각적으로 분석하고 해결할 수 있습니다.
챕터 3: 디버깅 시각화 옵션
Why
NOTE복잡한 레이아웃에서는 각 위젯의 경계나 정렬 기준선이 어디인지 파악하기 어렵습니다. 시각화 옵션을 켜면 위젯의 경계, 패딩, 마진 등을 화면에서 직접 확인할 수 있습니다.
디자인 의도대로 레이아웃이 구성되었는지 검증할 때 유용합니다.
What
NOTEWidget Inspector는 여러 시각화 옵션을 제공합니다.
옵션 설명 사용 시점 Slow Animations 애니메이션 속도 감소 애니메이션 디버깅 Show Guidelines 정렬 가이드라인 표시 정렬 확인 Show Baselines 텍스트 기준선 표시 텍스트 정렬 확인 Highlight Repaints 다시 그려지는 영역 표시 성능 최적화 Highlight Oversized Images 과도하게 큰 이미지 표시 이미지 최적화
How
TIP시각화 옵션 활성화하기
Widget Inspector 툴바에서 원하는 옵션의 버튼을 클릭합니다. 또는 코드에서 프로그래밍 방식으로 활성화할 수 있습니다.
import 'package:flutter/rendering.dart';void main() {// 레이아웃 경계 표시debugPaintSizeEnabled = true;// 기준선 표시debugPaintBaselinesEnabled = true;// 포인터 영역 표시debugPaintPointersEnabled = true;runApp(const MyApp());}Slow Animations
애니메이션을 5배 느리게 재생합니다.
// 코드에서 활성화import 'package:flutter/scheduler.dart';timeDilation = 5.0; // 5배 느리게복잡한 애니메이션의 각 단계를 분석할 때 유용합니다.
Show Guidelines
┌─────────────────────────────────────┐│ ┌─────┐ ││ │Text │ ← 가이드라인으로 정렬 확인 ││ └─────┘ ││ - - - - - - - - - - - - - - - - - │ ← 가이드라인│ ┌─────────────────┐ ││ │ Button │ ││ └─────────────────┘ │└─────────────────────────────────────┘위젯들의 정렬이 맞는지 시각적으로 확인할 수 있습니다.
Show Baselines
텍스트 위젯의 기준선을 표시합니다. 다른 크기의 텍스트가 같은 기준선에 정렬되는지 확인할 때 사용합니다.
Row(crossAxisAlignment: CrossAxisAlignment.baseline,textBaseline: TextBaseline.alphabetic,children: [Text('Big', style: TextStyle(fontSize: 24)),Text('Small', style: TextStyle(fontSize: 12)),],)Highlight Repaints
다시 그려지는(repaint) 영역에 랜덤 색상 테두리를 표시합니다.
debugRepaintRainbowEnabled = true;자주 다시 그려지는 위젯은 성능에 영향을 줄 수 있습니다. 불필요한 repaint가 발생하는 위젯을 찾아
RepaintBoundary4로 격리할 수 있습니다.// 불필요한 repaint 격리RepaintBoundary(child: AnimatedWidget(), // 자주 변경되는 위젯)Highlight Oversized Images
실제 표시 크기보다 큰 이미지를 강조합니다.
┌─────────────────────────────────────┐│ ┌─────────────────┐ ││ │ │ ││ │ INVERTED │ ← 과도하게 큰 ││ │ (반전 표시) │ 이미지 ││ │ │ ││ └─────────────────┘ │└─────────────────────────────────────┘1000x1000 픽셀 이미지를 100x100 영역에 표시하면 메모리 낭비입니다. 적절한 크기로 리사이징하거나
cacheWidth/cacheHeight를 지정해야 합니다.// 메모리 효율적인 이미지 로딩Image.network('https://example.com/large-image.jpg',cacheWidth: 200, // 캐시 크기 제한cacheHeight: 200,)
Watch out
WARNING시각화 옵션 사용 시 주의사항입니다.
성능 영향:
- 시각화 옵션을 켜면 앱 성능이 저하됩니다.
- 디버깅이 끝나면 반드시 끄세요.
프로덕션 코드에서 제거:
// 디버그 모드에서만 활성화assert(() {debugPaintSizeEnabled = true;return true;}());
assert블록은 릴리스 빌드에서 제거되므로 안전합니다.Highlight Repaints 해석 주의:
- 모든 repaint가 문제는 아닙니다.
- 애니메이션, 스크롤 등은 자연스러운 repaint입니다.
- 정적인 UI가 계속 repaint되면 문제입니다.
결론: 시각화 옵션을 활용하면 레이아웃과 렌더링 문제를 쉽게 발견할 수 있습니다.
한계
Widget Inspector는 UI 디버깅에 강력하지만 다음과 같은 제한이 있습니다.
- 성능 분석 부족: 렌더링 성능 문제는 Performance 탭을 사용해야 한다.
- 복잡한 트리: 위젯이 수천 개이면 탐색이 어려워진다.
- 런타임 전용: 빌드 타임 에러는 IDE의 정적 분석을 사용해야 한다.
- 일부 위젯 미지원: 일부 RenderObject는 상세 정보가 제한적으로 표시된다.
Footnotes
-
Widget Inspector(위젯 인스펙터): Flutter DevTools의 핵심 도구로, 실행 중인 앱의 위젯 트리를 시각적으로 탐색하고 분석할 수 있게 한다. ↩
-
Constraints(제약 조건): 위젯이 차지할 수 있는 최소/최대 크기를 정의한다. 부모 위젯이 자식에게 전달하며, 자식은 이 범위 내에서 크기를 결정한다. ↩
-
Layout Explorer(레이아웃 익스플로러): Widget Inspector의 기능으로, Row, Column 같은 Flex 레이아웃을 시각적으로 분석하고 속성을 실시간으로 조절할 수 있다. ↩
-
RepaintBoundary(리페인트 바운더리): 하위 위젯의 다시 그리기를 격리하는 위젯이다. 자식 위젯이 repaint될 때 부모에게 영향을 주지 않는다. ↩
공유
이 글이 도움이 되었다면 다른 사람과 공유해주세요!