목차
- 사용된 기능 설명
- 사용 예시
- 메소드 및 변수 선언
- Scaffold 작성
- 기타 메소드 작성
- 테스트
✅ 사용된 기능 설명
- SingleTickerProviderStateMixin : flutter에서 애니메이션을 다룰 때 쓰이는 mixin
** 하단에 TabController 사용을 위해 씀
** TabController 를 쓰려면 vsync 가 필요한데, 그걸 쓰기 위해 SingleTickerProviderStateMixin (또는 TickerProviderStateMixin) 을 꼭 써야 함 - mixin : 여러 클래스에서 공통으로 쓰이는 기능(코드)을 재사용하기 위한 도구
- TabController : 탭(Tab)과 탭에 연결된 화면(View)을 동기화해서 관리하는 컨트롤러
** TabBar와 TabBarView 양쪽에 알려주면서 화면 전환을 자연스럽게 연결해주는 역할
** 애니메이션을 쓰려면 vsync 라는 게 필요하며, 화면이 보일 때만 애니메이션을 돌려서 성능을 아끼는 장치
** vsync 는 TickerProvider 타입이어야 하고, StatefulWidget 의 State 클래스에서 TickerProvider 를 제공해야 함 - addListener : 객체(TabController, TextEditingController...)의 상태 변화가 일어날 때 실행할 동작을 등록하는 메소드
- setState() : StatefulWidget에서 상태(State)가 변했음을 Flutter 프레임워크에 알려 UI를 다시 그리게 하는 메소드
** StatefullWidget 에서만 사용 가능
** StatelessWidget에선 사용 불가 - TabBarView : TabController 와 연결되는 페이지 전환 위젯
- TabBar : TabController 와 연결되는 탭 버튼 담당 위젯
** TabBar의 tabs 요소 내의 디폴트는 흰색 글씨라서 변경 필요 - BuildContext : Flutter 에서 BuildContext 는 위젯이 어디에 위치해 있는지에 대한 메타 정보를 담은 것
- context : 현재 빌드되는 위치의 BuildContext
✅ 사용 예시
1️⃣ 메소드 및 변수 선언
- 애니메이션 기능 사용을 위해 Single... 추가
- 애니메이션 기능 사용을 위해 TabController 선언
- 앱 초기화, 앱 종료 메소드 작성

2️⃣ Scaffold 작성
- 각 아이콘 별 클릭 시, '스르륵'하게 화면 넘어가는 기능을 위해 TabBarView 사용
- bottomNavigationBar 작성

3️⃣ 기타 메소드 작성
- body 부분에 사용될 메소드 작성

4️⃣ 테스트
✔️ 사용된 코드
// SingleTickerProviderStateMixin : flutter에서 애니메이션을 다룰 때 쓰이는 mixin
// ** 하단에 TabController 사용을 위해 씀
// ** TabController 를 쓰려면 vsync 가 필요한데, 그걸 쓰기 위해 SingleTickerProviderStateMixin (또는 TickerProviderStateMixin) 을 꼭 써야 함
// mixin : 여러 클래스에서 공통으로 쓰이는 기능(코드)을 재사용하기 위한 도구
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{
late TabController _tabController;
int _selectedIndex = 0; // bottom 아이콘 별 index
// vsync : 애니메이션의 "프레임 동기화" 담당
@override
void initState(){ // 앱 초기화
super.initState(); // 부모(super) 초기화(initState) 호출
_tabController = TabController(length: 3, vsync: this); // this : 현재 클래스의 인스턴스. 즉, _MyHomePageState
_tabController.addListener(
// setState() : StatefullWidget 에서만 사용 가능 (StatelessWidget에선 사용 불가)
() => setState(() => _selectedIndex = _tabController.index));
}
@override
void dispose(){ // 앱 종료 시, 자원들 삭제
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Test App"),
),
// 앱 하단 아이콘 별 클릭 시, 화면 전환이 '스르륵'
body: TabBarView( // TabBarView : TabController 와 연결되는 페이지 전환 위젯
controller: _tabController,
children: [
tabContainer(context, Colors.indigo, "Friends Tab"),
tabContainer(context, Colors.amber, "Chats Tab"),
tabContainer(context, Colors.blueGrey, "Settings Tab"),
],
),
bottomNavigationBar: SizedBox(
height: 80,
child: TabBar( // TabBar : TabController 와 연결되는 탭 버튼 담당 위젯
controller: _tabController,
indicator: BoxDecoration(), // indicator 없애기
labelStyle: TextStyle(fontSize: 12,),
labelColor: Colors.black, // TabBar의 tabs 요소 내의 디폴트는 흰색 글씨라서 변경 필요
tabs: [
Tab(
icon: Icon(_selectedIndex == 0 ? Icons.person : Icons.person_outline),
text: "Friends"
),
Tab(
icon: Icon(_selectedIndex == 1 ? Icons.chat : Icons.chat_outlined),
text: "Chats"
),
Tab(
icon: Icon(_selectedIndex == 2 ? Icons.settings : Icons.settings_outlined),
text: "Settings"
),
]
),
),
);
}
Widget tabContainer(BuildContext con, Color tabColor, String tabText){
return Container(
width: MediaQuery.of(con).size.width, // con : 해당 메소드가 사용된 위젯
height: MediaQuery.of(con).size.height,
color: tabColor,
child: Center(
child: Text(
tabText,
style: TextStyle(
color: Colors.white,
)
)
)
);
}
}
'IT 언어 > Flutter' 카테고리의 다른 글
| [Flutter] BLoC 패턴 (factory, dynamic, required, rxdart, http) [맥북💻] (0) | 2025.09.25 |
|---|---|
| [Flutter] 아래로 스와이프하여 새로고침 (RefreshIndicator) [맥북💻] (0) | 2025.09.23 |
| [Flutter] 데이터를 기기에 저장하기 (SharedPreferences) [맥북💻] (0) | 2025.09.20 |
| [Flutter] JSON 데이터 불러오기 (Future, async) [맥북💻] (0) | 2025.09.16 |
| [Flutter] 페이지 이동 (Navigator) [맥북💻] (0) | 2025.09.15 |