Flutter는 모든 UI를 위젯(Widget) 으로 구성하며,
각 위젯은 상태 관리 방식에 따라 StatelessWidget / StatefulWidget 으로 구분된다.
import 'package:flutter/material.dart';
class MyHomePage extends StatefulWidget {
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _selectedIndex = 0;
final List<Widget> _pages = [
Center(child: Text("홈 화면")),
Center(child: Text("검색 화면")),
Center(child: Text("설정 화면")),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
Widget build(BuildContext context) {
return Scaffold(
body: _pages[_selectedIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onItemTapped,
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: '홈'),
BottomNavigationBarItem(icon: Icon(Icons.search), label: '검색'),
BottomNavigationBarItem(icon: Icon(Icons.settings), label: '설정'),
],
),
);
}
}
💡 Tip:
BottomNavigationBar를 사용할 때는 반드시 List + Index 조합으로 페이지를 관리하는 것이 효율적이다.
class MyTitle extends StatelessWidget {
final String title;
const MyTitle({required this.title});
Widget build(BuildContext context) {
return Text(title, style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold));
}
}
🧠 비교 요약
| 구분 | StatefulWidget | StatelessWidget |
| :-- | :-- | :-- |
| 상태 관리 | ✅ 가능 | ❌ 불가능 |
| 재렌더링 | 가능 (setState()) | 불가능 |
| 사용 예시 | 탭, 버튼, 입력 필드 등 | 로고, 텍스트, 아이콘 등 |
| 속성 | 설명 |
|---|---|
initialRoute | 앱 시작 시 표시할 최초 경로 지정 |
routes | 경로와 해당 위젯을 연결하는 Map 구조 |
void main() {
runApp(MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => HomePage(),
'/about': (context) => AboutPage(),
},
));
}
| 함수 | 설명 |
|---|---|
Navigator.pushNamed(context, '/about') | 지정한 경로로 페이지 이동 |
Navigator.pop(context) | 가장 최근에 열었던 페이지로 돌아감 |
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/about');
},
child: Text('About 페이지로 이동'),
);
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('뒤로가기'),
);
💡 Tip:
Navigator는 스택(Stack) 구조로 동작한다.
- push : 새 페이지를 스택 위에 추가
- pop : 현재 페이지를 스택에서 제거 (이전 페이지로 복귀)