원래 디자인을 끝낸 다음에 개발에 착수하는 것이 맞지만 그냥 개발하고 싶을 때 개발하고 디자인하고 싶을 때 디자인 할 것이기 때문에 Figma에서 만든 탭바를 구현해 줄 것이다.
이것들을 구현해 줄 것이다.
파일 이름은 MainTab으로 할 것인데 탭 동작을 관리하는 파일이므로 이렇게 명명해 줬다.
원래 이제 바텀 내비게이션으로 구현할 땐 Scaffold의 body 파라미터에는 IndexedStack같은 위젯을 배치시켜 스크린들을 관리시키고 bottomnavigationBar같은 파라미터에는 BottomnavigationBar 같은 위젯을 배치시켜 만들게 될 것이다.
또 IndexedStack과 BottomnavigationBar 위젯을 사용하기 때문에 인덱스를 관리할 currentIndex와 같은 인스턴스를 생성하고 토글 동작을 만들어줘야 할 것이다. 이는 아래와 같은 모습을 띄게 된다.
class _MainTabState extends State<MainTab> {
int currentIndex = 0;
void setIndex(int value) {
setState(() {
currentIndex = value;
});
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: DefaultTabController(
length: 4,
child: Scaffold(
body: IndexedStack(
index: currentIndex,
children: [
Scaffold(),
Scaffold(),
Scaffold(),
Scaffold(),
],
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: ...),
BottomNavigationBarItem(icon: ...),
BottomNavigationBarItem(icon: ...),
BottomNavigationBarItem(icon: ...),
],
),
),
),
);
}
}
허나 이번에 구현할 방식은 IndexedStack 위젯도 사용하지 않을 것이고 BottomnavigationBar위젯도 사용하지 않을 것이다.
그렇다면 무엇을 사용할 것이냐? 간단하다. 탭을 구현할 것이기에 Flutter에서 탭을 만들 때 엄청나게 쉽게 만들 수 있도록 도와주는 TabBarView위젯과 TabBar위젯을 사용할 것이다.
TabBarView와 TabBar는 기본적으로 TabController?타입의 controller 파라미터를 사용해서 컨트롤러를 넣어줘야 하는데 flutter.docs 봐보니까 굳이 그렇게 할 필요도 없어서 DefaultTabController를 사용해서 간단하게 구현해 줬다.
https://docs.flutter.dev/cookbook/design/tabs
Work with tabs
How to implement tabs in a layout.
docs.flutter.dev
기본이 되는 구조는 아래와 같다.
@override
Widget build(BuildContext context) {
return SafeArea(
child: DefaultTabController(
length: 4,
child: Scaffold(
body: TabBarView(
children: [
Scaffold(),
Scaffold(),
Scaffold(),
Scaffold(),
],
),
bottomNavigationBar: TabBar(
tabs: [
Text('알람'),
Text('세계시각'),
Text('스톱워치'),
Text('타이머'),
],
),
),
),
);
}
SafeArea로 화면을 감싸주고 DefaultTabController위젯을 사용해서 탭 수를 명명해 준다.
그리고 이제 핵심인 bottomnavigationBar 부분에는 BottomnavigationBar 대신 그냥 바로 TabBar를 사용해 주면 되겠다.
이제 디자인을 추가하면 된다.
가장 먼저 색을 바꿔주자.
bottomNavigationBar: TabBar(
indicatorColor: kBlack,
labelColor: kBlack,
unselectedLabelColor: kGray,
그다음에 보이는 문제가 무슨 탭들이 바닥에 달라붙어 있는 것인데 이것을 해결하기 위해선 먼저 TabBar의 자체적인 크기를 키워줘야 한다. FlutterInspector에 있는 show guidlines을 켜주면 아래와 같이 나타나게 되는데 지금 보면 선택 영역 자체도 작은 것을 알 수 있다. 그렇기에 크기를 키워줄 뿐만 아니라 선택영역도 늘려줘야 한다.
구현하는 방법은 간단하다. TabBar를 Container로 감싸고 색과 사이즈를 먹여주면 된다.
또한 TabBar의 파라미터인 labelPadding을 사용해서 상하에 패딩을 먹여주면 자체적으로 영역을 확장하게 된다.
bottomNavigationBar: Container(
color: kBackgroundColor,
height: 56,
child: TabBar(
labelPadding: EdgeInsets.symmetric(
vertical: 18,
),
indicatorColor: kBlack,
labelColor: kBlack,
unselectedLabelColor: kGray,
tabs: [
Text('알람'),
Text('세계시각'),
Text('스톱워치'),
Text('타이머'),
],
),
),
이렇게 크기가 잘 늘어난 모습을 볼 수 있다. 오버레이를 확인해 봐도 마찬가지다.
또한 자연스럽게도 TabBarView 부분에서는 선택 시 그 화면으로 넘어가게 된다.