Flutter 하단 탭바 만드는 방법
요즘 대부분 많은 앱에서 하단 탭바를 사용하고 있습니다.
대표적으로 카카오톡, 인스타그램, 유튜브 등이 있죠.
여러 화면에 접근하기 쉬워서 많이 사용하는 것 같아요.
하단 탭바 만드는 방법은 생각보다 간단해요.
1. SingleTickerProviderStateMixin 사용
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen>
with SingleTickerProviderStateMixin { }
2. TabController _tabController, int _selectedIndex 변수 선언
late TabController _tabController;
int _selectedIndex = 0;
_selectIndex는 사용자가 선택한 탭 인덱스 번호입니다.
3. initState()와 tabController 초기화 및 리스너 추가, dispose() 에서 컨트롤러 해제
@override
void initState() {
super.initState();
_tabController = TabController(length: 3, vsync: this);
_tabController.addListener(
() => setState(() => _selectedIndex = _tabController.index),
);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
TabController 개수를 3으로 설정해주고,
addListener를 사용해서 탭 바가 클릭될 경우 _selectedIndex 값을 변경하도록 setState() 해줍니다.
4. build()에서 bottomNavigationBar 위젯 배치
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Title"), backgroundColor: Colors.white),
bottomNavigationBar: SizedBox(
height: 70,
child: TabBar(
indicatorColor: Colors.red,
labelColor: Colors.black,
controller: _tabController,
tabs: <Widget>[
Tab(icon: Icon(Icons.schedule), text: "스케줄"),
Tab(icon: Icon(Icons.calendar_month), text: "캘린더"),
Tab(icon: Icon(Icons.query_stats), text: "통계"),
],
),
),
body: tabContainer()
);
}
중요한 부분은 TabBar() 입니다.
indicatorColor는 선택된 탭바 하단 인디케이터 색상,
tabs는 탭바에 표시될 탭을 작성해주면 됩니다.
icon과 text 등 원하는 것만 추가해도 됩니다.
그리고 body는 탭 선택 시 원하는 화면이 표시되도록 tabContainer 함수를 호출해줍니다.
5. 탭 선택 시 화면 연결 (tabContainer())
StatelessWidget tabContainer() {
switch (_selectedIndex) {
case 0:
return ScheduleScreen();
case 1:
return CalendarScreen();
case 2:
return StatsScreen();
}
return Container(child: Text("data"));
}
선택된 탭(selectedIndex)에 따라 원하는 화면을 출력해주면 됩니다.
참고용 화면) ScheduleScreen, CalendarScreen(), StatsScreen()
class ScheduleScreen extends StatelessWidget {
const ScheduleScreen({super.key});
@override
Widget build(BuildContext context) {
return Container(
color: Colors.green,
child: Center(child: Text("스케줄 화면!", style: TextStyle(fontSize: 20),)),
);
}
}
class CalendarScreen extends StatelessWidget {
const CalendarScreen({super.key});
@override
Widget build(BuildContext context) {
return Container(
color: Colors.blue,
child: Center(child: Text("캘린더 화면!", style: TextStyle(fontSize: 20),)),
);
}
}
class StatsScreen extends StatelessWidget {
const StatsScreen({super.key});
@override
Widget build(BuildContext context) {
return Container(
color: Colors.amber,
child: Center(child: Text("통계 화면!", style: TextStyle(fontSize: 20),)),
);
}
}
예제 화면)



전체 소스코드)
// home_screen.dart
import 'package:colab_note/screens/schedule/calendar_screen.dart';
import 'package:colab_note/screens/schedule/schedule_screen.dart';
import 'package:colab_note/screens/schedule/stats_screen.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen>
with SingleTickerProviderStateMixin {
late TabController _tabController;
int _selectedIndex = 0;
@override
void initState() {
super.initState();
_tabController = TabController(length: 3, vsync: this);
_tabController.addListener(
() => setState(() => _selectedIndex = _tabController.index),
);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Title"), backgroundColor: Colors.white),
bottomNavigationBar: SizedBox(
height: 70,
child: TabBar(
indicatorColor: Colors.red,
labelColor: Colors.black,
controller: _tabController,
tabs: <Widget>[
Tab(icon: Icon(Icons.schedule), text: "스케줄"),
Tab(icon: Icon(Icons.calendar_month), text: "캘린더"),
Tab(icon: Icon(Icons.query_stats), text: "통계"),
],
),
),
body: tabContainer(),
);
}
StatelessWidget tabContainer() {
switch (_selectedIndex) {
case 0:
return ScheduleScreen();
case 1:
return CalendarScreen();
case 2:
return StatsScreen();
}
return Container(child: Text("data"));
}
}
간단하게 구현 완료!
'IT > Flutter' 카테고리의 다른 글
| [Flutter] Safe Area 적용 방법 (0) | 2025.10.11 |
|---|