하단에 위치하는 네비게이션바를 구현하는 방법은 크게 3가지가 있다.
약간의 차이점이 있으니 필요에 따라 사용하면 되겠다.
DefaultTabController 사용
return MaterialApp(
title: 'chat used firebase',
theme: ThemeData(primaryColor: Colors.white),
home: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text('fire chat App'),
),
body: TabBarView(
children: [
Text('홈 스크린'),
Text('채팅 스크린'),
Text('마이 스크린'),
],
),
bottomNavigationBar: TabBar(tabs: [
Tab(
icon: Icon(Icons.home),
text: 'home',
),
Tab(
icon: Icon(Icons.chat),
text: 'chat',
),
Tab(
icon: Icon(Icons.people),
text: 'my',
)
]),
)),
);
DefaultTabController 위젯의 child로 Scaffold를 가지고,
Scaffold의 body에 TabBarVIew, bottomNavigationBar에 TabBar을 준다.
TabBar의 tabs에 Tab을 준다.
네비게이션 바 커스텀하기
class BottomBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: colorThemeYellow(), //색상
child: Container(
height: 70,
padding: EdgeInsets.only(bottom: 10, top: 5),
child: TabBar(
indicatorSize: TabBarIndicatorSize.label,
indicatorColor: colorThemeRed(),
indicatorWeight: 4,
labelColor: Colors.white,
unselectedLabelColor: Colors.black38,
labelStyle: TextStyle(
fontSize: 17, fontFamilyFallback: fontFamilyName('Yanolja')),
tabs: [
Tab(
icon: Icon(
Icons.home,
size: 20,
),
text: 'Home',
),
Tab(
icon: Icon(Icons.sort_by_alpha_rounded, size: 20),
text: 'Vocab',
),
Tab(
icon: Icon(
Icons.library_books,
size: 20,
),
text: 'Library',
),
Tab(
icon: Icon(
Icons.person,
size: 20,
),
text: 'MyPage',
)
],
),
),
);
}
}
DefaultTabController의 bottomNavigatorBar 속성에 위의 코드와 같이 Container 등으로 감싼 Tabbar를 주면, 원하는 모양으로 커스텀 할 수 있다.
장점
- 다른 함수 없이 위젯만으로 정말 간단하게 네비게이션바를 만들 수 있다.
- DefaultTabController의 특징은 선택된 탭에 Indicator가 함께 표시된다.
- 화면을 스와이프해서 탭을 이동할 수 있고, 화면이 넘어가는 애니메이션이 있다.
- 아이콘의 색상과 텍스트의 색상을 변경할 수 있다.
- 아이콘 없이 텍스트만으로도 네비게이션바를 만들 수 있다. (다른 방법들은 아이콘이 필수이다.)
- 네비게이션 바의 스크롤이 가능하다.
특이점
- 네비게이션바의 세로 사이즈나, 배경 색상을 바꾸고싶다면 TabBar를 Container로 감싸 Container의 속성에서 지정해주어야한다.
- TabBarView와 TabBar에 Controllor를 등록하여 사용할 수 있다.
- stateless 클래스로도 가능하다.
속성
indicator와 Icon, Label의 색상, 크기는 TabBar 속성으로 설정할 수 있다.
TabBar(
labelColor: Colors.white, //텍스트와 아이콘 색상 변경
unselectedLabelColor: Colors.white54,
indicatorColor: Colors.white, //선택된 탭의 밑줄
indicatorSize: TabBarIndicatorSize.label, //밑줄 너비
indicatorWeight: 2, //밑줄 길이
특수 속성
네비게이션 바의 스크롤 유무에 따라 레이아웃이 변경된다.
해당 속성이 true고, 항목이 적을 경우 왼쪽에 밀착이 되고, false(기본값)면 간격이 일정하게 배열된다.
TabBarView(
physics: NeverScrollableScrollPhysics(), //스와이프가 안되도록 한다.
TabBar(
isScrollable: true, //네비게이션 바의 스크롤이 가능하다.
TabController의 사용
첫 번째 방법이 DefaultTabControllor를 사용해 제공된 Controllor로 Tab을 움직였다면
아래 예제는 TabControllor를 사용한다.
//반드시 stateful 클래스여야 하며, 상태 클래스에 with로 아래의 티커를 지정해주어야한다.
//내부적으로 애니메이션 효과를 위함이다.
class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateMixin {
TabController _controller; //DefaultTabControllor 대신 사용되는 컨트롤러이다.
//반드시 선언만 이 곳에서 해주고 정의는 init에서 해주어야한다.
void initState(){
//반드시 정의가 init에서 이루어져야한다.
_controller = TabController(length : 3, vsync : this); //vsync는 무조건 this
...
Scaffold(
body: TabBarView(
controller: controller,
children: [Text('1'), Text('2'), Text('3'), Text('4')]),
bottomNavigationBar: TabBar(controller: controller, tabs: [
Tab(
icon: Icon(Icons.home),
text: '1',
),
Tab(
icon: Icon(Icons.home),
text: '2',
),
Tab(
icon: Icon(Icons.home),
text: '3',
),
Tab(
icon: Icon(Icons.home),
text: '4',
)
]),
));
첫 번째 방법과 디자인적이나 기타 요소들은 동일하며, 일반적으론 사용되지 않아, 이런게 있구나 정도만 생각하면 되겠다. 높은 수준의 커스터마이징이 필요하다면 이 방법을 사용해 위젯을 제작하곤 한다.
BottomNavigationBar
Scaffold의 body에 위젯 List[index] 형태로 보여질 위젯을 정해주고 탭을 선택할 때 index가 변화하도록 하는 방법이다.
BottomNavigationBar는 currentIndex라는 선택 탭의 번호를 지정하는 속성을 가지고 있는데, 이 속성의 값은 탭의 선택에 따라 자동으로 변경되는 것이 아니라 아래의 예제처럼 onTap을 정의해주어야한다. onTap에서 screenIndex를 value로 변경하면 body의 List 요소와 탭이 함께 변경되어 우리가 아는 것처럼 하단 탭 부분과 화면이 바뀌게 된다.
int screenIndex = 0;
List<Widget> screenList = [Text('홈스크린'), Text('채팅 스크린'), Text('마이 스크린')];
Scaffold(
appBar: AppBar(
title: Text('fire chat App'),
),
body: screenList[screenIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: screenIndex,
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'home'),
BottomNavigationBarItem(icon: Icon(Icons.chat), label: 'chat'),
BottomNavigationBarItem(icon: Icon(Icons.people), label: 'my')
],
onTap: (value) {
setState(() { //상태 갱신이 되지 않으면 동작을 하지 않음
screenIndex = value;
});
},
));
j
장점
- 앞선 방법이 하단 바의 색상을 바꾸기 위해서 하단 바를 Container로 감싸야했지만, backgroundColor 속성이 있다.
- 가장 일반적으로 사용되는 방법이다.
- 현재 선택된 탭의 Index 번호를 얻을 수 있다.
속성
- selected / unselected 속성으로 선택 및 비선택된 탭의 디자인을 변경할 수 있다.
단점
- 인디케이터는 불가능하다.
- 스와이프가 불가능하다.
- 전환되는 애니메이션이 없다.
요약하자면
탭 전환시 스와이프 되는 애니메이션이 필요하다면 첫 번째 방법을,
그렇지 않다면 세 번째 방법을 사용하면 된다.
'Flutter > Flutter Widget Basic' 카테고리의 다른 글
[플러터] Toast 메시지 (Snack bar) 생성하기 (0) | 2021.01.07 |
---|---|
[플러터] onClick 속성이 가능한 Text 위젯 (0) | 2020.11.21 |
[플러터] Inkwell의 이펙트 제거 (0) | 2020.09.24 |
[Flutter] Appbar에서 알아야할 속성 (0) | 2020.08.22 |
[Flutter] Main과 MateriaApp의 필수적인 속성 (0) | 2020.08.15 |