[플러터] bottom Navigation을 구현하는 3가지 방법

2020. 9. 28. 21:18·Flutter/Flutter Widget Basic

하단에 위치하는 네비게이션바를 구현하는 방법은 크게 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',
            )
          ],
        ),
      ),
    );
  }
}

 

bottomNavigatorBar를 커스텀 할 수 있다.

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, //네비게이션 바의 스크롤이 가능하다.

isScrollable = true

 

isScrollable = false

 

 

 


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
'Flutter/Flutter Widget Basic' 카테고리의 다른 글
  • [플러터] Toast 메시지 (Snack bar) 생성하기
  • [플러터] onClick 속성이 가능한 Text 위젯
  • [플러터] Inkwell의 이펙트 제거
  • [Flutter] Appbar에서 알아야할 속성
박유상의 개발블로그
박유상의 개발블로그
개발블로그
  • 박유상의 개발블로그
    박유상의 개발블로그
    박유상의 개발블로그
  • 전체
    오늘
    어제
    • 전체 (134)
      • Who am I (10)
        • Portfolio (4)
        • Reminiscence (5)
        • Oversea (1)
        • SiliconValley (0)
      • React (36)
        • React Basic (15)
        • React Tech (5)
        • JavaScript (7)
        • TypeScript (3)
        • CSS&HTML (3)
        • Firebase (3)
      • NodeJS (1)
        • NodeJS Basic (1)
      • Flutter (55)
        • Flutter Widget Design (5)
        • Flutter Widget Basic (8)
        • Flutter Tech (18)
        • Flutter Issue (7)
        • Flutter Web (6)
        • About Flutter (2)
        • Firebase (1)
        • Dev Env (1)
        • Dart (7)
      • Programming (31)
        • Web (1)
        • General (0)
        • Algorithm (25)
        • Python (1)
        • VS Code (2)
      • Django (0)
  • 블로그 메뉴

    • Who I AM
    • React
    • NodeJS
    • Flutter
    • Programming
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    useState
    useTranslation
    Flutter
    자바스크립트
    프로그래머스
    Lingory
    JSON
    알고리즘
    DP
    탐욕법
    JavaScript
    CSS
    react
    useRef
    flutter web
    HTML
    플러터
    Redux
    github
    웹
    map
    플러터 웹
    Firebase
    리액트
    링고리
    Python
    포트폴리오
    TypeScript
    DART
    파이썬
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
박유상의 개발블로그
[플러터] bottom Navigation을 구현하는 3가지 방법
상단으로

티스토리툴바