1. UI 골격 및 레이아웃 구성
번호 |
위젯 이름 |
설명 |
1 |
Container |
스타일, 여백, 색상, 크기 등 거의 다 되는 만능 박스 |
2 |
Padding |
여백 추가용 래퍼 위젯 |
3 |
Column |
VStack (수직 정렬) |
4 |
Row |
HStack (수평 정렬) |
5 |
SizedBox |
고정 크기 or Spacer 용도 |
6 |
Expanded |
남는 공간 채우기용 (flex ) |
7 |
Flexible |
Expanded 보다 유연한 버전 |
8 |
Align / Center |
위치 정렬 용도 |
9 |
Stack |
ZStack (위젯 겹치기) |
10 |
SafeArea |
노치, 상태바 영역 피하기 |
// 수직 정렬 (VStack)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Hello'),
SizedBox(height: 16),
Text('World'),
],
)
// 수평 정렬 (HStack)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.menu),
Icon(Icons.search),
],
)
// Stack (ZStack)
Stack(
children: [
Container(color: Colors.blue),
Positioned(
top: 20,
left: 20,
child: Text('위에 겹쳐지는 요소'),
),
],
)
// 패딩
Padding(
padding: const EdgeInsets.all(16.0),
child: Text('Padding 적용됨'),
)
// 여백 / Spacer
SizedBox(height: 20),
Container(
padding: const EdgeInsets.all(12),
margin: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: Colors.grey[300]!),
),
child: Text('박스 안에 텍스트'),
)
// 정렬
Align(
alignment: Alignment.centerRight,
child: Text('오른쪽 정렬'),
)
// SafeArea: 노치, 상태바 피하기
SafeArea(
child: Text('안전한 영역'),
)
// MediaQuery: 디바이스 크기 사용
double width = MediaQuery.of(context).size.width;
// LayoutBuilder: 반응형 조건 분기
LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth < 600) {
return Text('모바일 UI');
} else {
return Text('태블릿/웹 UI');
}
},
)
2. 텍스트, 입력, 버튼 등 UI 구성 요소
번호 |
위젯 이름 |
설명 |
11 |
Text |
텍스트 출력의 기본 |
12 |
TextField |
사용자 입력 받기 |
13 |
ElevatedButton |
기본 버튼 |
14 |
TextButton |
플랫한 텍스트 버튼 |
15 |
OutlinedButton |
테두리 있는 버튼 |
16 |
Icon / IconButton |
아이콘, 아이콘 버튼 |
17 |
Image.asset / Image.network |
이미지 표시 |
18 |
ListView |
스크롤 가능한 리스트 |
19 |
ListTile |
리스트 항목 구성용 |
20 |
Form / FormField |
유효성 검사 포함된 폼 필드 |
TextField(
controller: myController,
decoration: InputDecoration(
hintText: '입력하세요',
border: OutlineInputBorder(),
),
)
ElevatedButton(
onPressed: () => print('클릭됨'),
child: Text('버튼'),
)
TextButton(
onPressed: () {},
child: Text('텍스트 버튼'),
)
IconButton(
icon: Icon(Icons.favorite),
onPressed: () {},
)
3. 스크롤, 반응형 레이아웃 제어
번호 |
위젯 이름 |
설명 |
21 |
SingleChildScrollView |
Column 등 스크롤 가능하게 감싸기 |
22 |
ScrollController |
스크롤 위치 제어 |
23 |
MediaQuery |
디바이스 화면 정보 가져오기 |
24 |
LayoutBuilder |
부모 사이즈에 따른 조건부 UI |
25 |
Wrap |
자동 줄바꿈 가능한 Row |
26 |
Visibility / Offstage |
조건부 렌더링/숨김 처리 |
27 |
AnimatedContainer |
부드러운 레이아웃 변화 |
28 |
GestureDetector |
클릭/스와이프 등 사용자 제스처 감지 |
29 |
Navigator / MaterialPageRoute |
페이지 이동, 라우팅 |
30 |
Scaffold |
앱 기본 구조 (AppBar, body, FAB 등) |
// 수직 스크롤 리스트
ListView(
children: [
ListTile(title: Text('항목 1')),
ListTile(title: Text('항목 2')),
],
)
// 빌더 방식
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(items[index]),
);
},
)
// SingleChildScrollView
SingleChildScrollView(
child: Column(
children: [ ... ],
),
)
// Navigator: 페이지 이동
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const DetailPage()),
);
// 상태변경
setState(() {
count++;
});
Scaffold(
appBar: AppBar(title: Text('My App')),
body: Center(child: Text('내용')),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),
)
4. 상태/비동기/애니메이션 관련
StatefulWidget
/ StatelessWidget
FutureBuilder
, StreamBuilder
Hero
, AnimatedSwitcher
Theme
, ThemeData
- 상태관리:
Provider
, Riverpod
, Bloc
, GetX
등