탭 바, 일반적으로 내비게이션 바라고 부르는 뷰를 만들어보자
많이 쓰이는 것들은 BottomNavigationBar, TabBar, PageView 등등
내비게이션 바, 페이지를 만드는데 사용할 수 있는 위젯은 다양하다.
이 중 TabBar를 사용해보자
보통 내비게이션 바에는 4개의 탭이 있고, 상단 또는 하단에 위치하게 된다.
4개의 탭을 생성해보자
TabBar(
indicatorColor: Colors.yellow, // 선택 영역 색깔
indicatorSize: TabBarIndicatorSize.tab, // 선택 영역 색 범위 탭 영역 전체 (길다란 선)
controller: _tabController, // 탭 컨트롤러
tabs: [
IgnorePointer(
child: IconButton(
onPressed: () {},
icon: const Icon(Icons.home_filled),
),
),
IgnorePointer(
child: IconButton(
onPressed: () {},
icon: const Icon(Icons.add_box_outlined),
),
),
IgnorePointer(
child: IconButton(
onPressed: () {},
icon: const Icon(Icons.list_alt),
),
),
IgnorePointer(
child: IconButton(
onPressed: () {},
icon: const Icon(Icons.person),
),
),
],
),
IconButton은 아이콘에 버튼 기능이 추가된 위젯이다.
아이콘을 버튼으로 사용하기 위함.
그런데 왜 IgnorePointer를 위로 감싸주었을까?
TabBar 에 넣어주는 tab들은 기본적으로 버튼 기능을 하는데 (탭을 누르면 이동해야하니까)
IconButton은 자기만의 버튼 영역이 있어서 IconButton 만을 누를 경우 탭 이동은 되지 않는다.
이렇게 눌리면 탭이 이동되지만
이렇게 눌리면 이동이 되지 않는다
이제 탭 버튼을 만들었으니 탭 이동시 같이 이동하는 페이지를 만들어보자
필자는 탭바를 상단에 뒀기 때문에 TabBarView 를 그 밑에 위치시켰다.
Expanded(
child: TabBarView(
controller: _tabController,
children: const [
Center(
child: Text('홈 화면'),
),
Center(
child: Text('추가 화면'),
),
Center(
child: Text('리스트 화면'),
),
Center(
child: Text('마이페이지'),
),
],
),
),
Expanded 로 TabBarView 를 감싸주지 않으면 에러가 발생하니 참고할 것
여기도 controller를 넣어줬는데 대체 얜 뭘까?
말그대로 탭을 다루게 해주는 controller
TabBar, TabBarView 가 나눠져있는데, 둘에게 동일한 controller 를 부여하여 동기화되어 동작할 수 있도록 하기 위함이다
class _HomePageState extends State<MyHomePage> with TickerProviderStateMixin {
late TabController _tabController;
@override
void initState() {
_tabController = TabController(length: 4, vsync: this);
super.initState();
}
with TickerProviderStateMixin 을 추가하고
TabController 에 vsync: this 를 추가해줘야 한다
with 의 개념은 어려울 수 있으니 다른 글을 참고하는걸 추천
간단히 설명하면 탭 바가 이동될 때 애니메이션이 들어가게 되는데 이 애니메이션을 다룰 수 있도록 도와주는 녀석이라고 보면 된다.
이게 어려우면 단순하게 적용하는 방법도 있다.
DefaultTabController 를 이용하는 방법이다.
body: DefaultTabController(
length: 4,
child: Center(
child: Column(
children: [
TabBar(
indicatorColor: Colors.yellow,
indicatorSize: TabBarIndicatorSize.tab,
tabs: [
DefaultTabController로 둘 모두를 감싸고, controller를 따로 부여하던걸 없애주면 된다.
어쨋든 이를 모두 적용하면 다음과 같이 나타난다
적용 영상
full code
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: DefaultTabController(
length: 4,
child: Center(
child: Column(
children: [
TabBar(
indicatorColor: Colors.yellow,
indicatorSize: TabBarIndicatorSize.tab,
tabs: [
IgnorePointer(
child: IconButton(
onPressed: () {},
icon: const Icon(Icons.home_filled),
),
),
IgnorePointer(
child: IconButton(
onPressed: () {},
icon: const Icon(Icons.add_box_outlined),
),
),
// IgnorePointer(
// child:
IconButton(
onPressed: () {},
icon: const Icon(Icons.list_alt),
),
// ),
IgnorePointer(
child: IconButton(
onPressed: () {},
icon: const Icon(Icons.person),
),
),
]),
const Expanded(
child: TabBarView(
children: [
Center(
child: Text('홈 화면'),
),
Center(
child: Text('추가 화면'),
),
Center(
child: Text('리스트 화면'),
),
Center(
child: Text('마이페이지'),
),
],
),
),
],
),
),
),
);
}
}
'APP > Flutter' 카테고리의 다른 글
[Flutter / 플러터] BLoc Pattern (블락 패턴)의 장점 (0) | 2023.07.12 |
---|---|
[Flutter / 플러터] 구글지도 사용하기 Google Map (2) | 2023.06.04 |
Flutter) Widget 생성 Class vs Function (0) | 2022.05.08 |
flutter) artemis 패키지 GraphQL LocalTime to Dart DateTime 변환 오류 (0) | 2022.04.24 |
Flutter CarouselSlider 한 페이지 여러 개 (0) | 2022.04.15 |