Flutter 공부하면서 자주 쓰이는 핵심 위젯과 개념들을 정리했습니다.
코드 예제와 함께 하나씩 정리해두면 나중에 프로젝트에서 바로 참고하기 좋습니다
1. ThemeData 클래스
앱 전체 스타일을 정의하는
ThemeData
를 설정하면, 일관된 디자인을 유지할 수 있습니다.import 'package:flutter/material.dart';
const MaterialColor primaryWhite = MaterialColor(
0xFFFFFFFF,
<int, Color>{
50: Color(0xFFFFFFFF),
100: Color(0xFFFFFFFF),
200: Color(0xFFFFFFFF),
300: Color(0xFFFFFFFF),
400: Color(0xFFFFFFFF),
500: Color(0xFFFFFFFF),
600: Color(0xFFFFFFFF),
700: Color(0xFFFFFFFF),
800: Color(0xFFFFFFFF),
900: Color(0xFFFFFFFF),
},
);
ThemeData theme() {
return ThemeData(
primarySwatch: primaryWhite,
appBarTheme: const AppBarTheme(
iconTheme: IconThemeData(color: Colors.blue),
),
);
}
- PrimaryColor
앱의 브랜드 아이덴티티를 나타내는 색상입니다. 기본은
blue
인데, 위 코드에서는 white
로 변경했습니다.- AccentColor
상호작용 요소(버튼, FAB 등)에 주로 쓰이는 포인트 색상입니다.
2. Drawer (Scaffold의 endDrawer)
Drawer는 화면의 가장자리에서 슬라이드하여 탐색 링크/메뉴를 보여주는 위젯입니다.
- 왼쪽 → 오른쪽:
drawer:
속성
- 오른쪽 → 왼쪽:
endDrawer:
속성
Scaffold(
appBar: AppBar(title: Text("Drawer Demo")),
endDrawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
DrawerHeader(
decoration: BoxDecoration(color: Colors.blue),
child: Text("메뉴", style: TextStyle(color: Colors.white)),
),
ListTile(title: Text("Home")),
ListTile(title: Text("Profile")),
],
),
),
body: Center(child: Text("Body Area")),
);
3. 위젯을 둥글게 만드는 방법
- Container + decoration
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(image: AssetImage('assets/profile.png')),
),
)
- ClipRRect / ClipOval
ClipOval(child: Image.asset('assets/profile.png'))
- CircleAvatar (가장 간단한 방법)
CircleAvatar(
radius: 40,
backgroundImage: AssetImage('assets/profile.png'),
)
4. TabBar & TabBarView
- TabBar : 탭 버튼(가로 행)
- TabBarView : 선택된 탭에 따라 화면 표시
TabController
로 두 위젯을 동기화해야 합니다.
class ProfileTab extends StatefulWidget {
@override
State<ProfileTab> createState() => _ProfileTabState();
}
class _ProfileTabState extends State<ProfileTab>
with SingleTickerProviderStateMixin {
@override
void initState() {
super.initState();
_tabController = TabController(length: 2, vsync: this);
}
@override
Widget build(BuildContext context) {
return Column(
children: [
TabBar(
controller: _tabController,
tabs: const [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.directions_transit)),
],
),
Expanded(
child: TabBarView(
controller: _tabController,
children: const [
ColoredBox(color: Colors.green),
ColoredBox(color: Colors.red),
],
),
),
],
);
}
}
5. SingleTickerProviderStateMixin
TabController
나AnimationController
는vsync
가 필요합니다.
State
클래스는 기본적으로TickerProvider
가 아니기 때문에,SingleTickerProviderStateMixin
을 섞어줍니다.
vsync: this
→ 현재 State 객체가 TickerProvider 역할을 하게 됩니다.
- SingleTickerProviderStateMixin : 애니메이션 1개만 필요할 때
- TickerProviderStateMixin : 여러 애니메이션이 필요할 때
추가 팁:
initState()
는 StatefulWidget이 최초 빌드될 때 단 한 번만 실행됩니다.
- 데이터가 바뀌어 리빌드 되어도
initState()
는 다시 실행되지 않습니다.
6. InkWell
- 모든 위젯을 버튼처럼 터치 가능하게 만드는 위젯입니다.
- Material 스타일의 잉크 효과(물결 효과)가 포함됩니다.
InkWell(
onTap: () => print("눌림!"),
child: Container(
padding: EdgeInsets.all(12),
child: Text("눌러보세요"),
),
)
참고) 버튼 구현 방법
TextButton
ElevatedButton
OutlinedButton
InkWell
(자유도가 높음)
7. GridView & Image.network
GridView는 수평/수직 방향으로 격자형 리스트를 만들어줍니다.
GridView.builder
는 아이템 개수가 많거나 동적일 때 사용합니다.TabBarView(
controller: _tabController,
children: [
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisSpacing: 10,
crossAxisCount: 3,
mainAxisSpacing: 10,
),
itemCount: 42,
itemBuilder: (context, index) {
return Image.network(
"https://picsum.photos/id/${index + 1}/200/200",
);
},
),
Container(color: Colors.red),
],
)
8. Align
자식 위젯을 원하는 위치에 정렬시킬 때 사용합니다.
Align(
alignment: Alignment.bottomRight,
child: Text("오른쪽 아래"),
)
9. 정리
ThemeData
로 앱 전체 스타일을 통일
Drawer
로 탐색 메뉴 구현 (drawer
/endDrawer
)
- 이미지를 둥글게:
Container.decoration
,ClipOval
,CircleAvatar
TabBar
+TabBarView
는TabController
와 연결
SingleTickerProviderStateMixin
으로 애니메이션/탭 전환 관리
InkWell
로 모든 위젯을 버튼처럼
GridView.builder
로 네트워크 이미지 그리드 표시
Align
으로 세밀한 위치 제어
Share article