[Flutter] BottomNavigationBar 사용하기 (feat. 3개 이상 아이템 적용시 하얀 배경 에러)

huny·2023년 8월 24일
0

flutter

목록 보기
10/18
post-thumbnail

앱 페이지 구성중 하단에 버튼들을 고정시켜놓고 사용하는 경우가 있다.
고정된 버튼을 클릭하면 각각 설정된 페이지로 이동한다.

Flutter에서도 해당 기능을 지원한다.
초반에 배우는 Scaffold Widget 내부 속성에 있는 BottomNavigationBar 가 그 주인공이다.

마지막에 전체 예제 해놓은거 있으니 설명 필요없으면 그거 긁어써도 될듯.

사용법

우선 Scaffold 내부에 bottomNavigationBar를 선언한다.
items 속성이 required. 즉 필수로 들어가야 한다.

Scaffold(
        bottomNavigationBar: BottomNavigationBar(
        items: const [],
        );

items는 하단 NavigationBar에 들어갈 버튼들이 들어가게 된다.
아무 위젯이나 넣을수는 없고, BottomNavigationBarItem을 넣어줘야 한다.

기본적인 활용 방식은 아래와 같다.

BottomNavigationBarItem(
   icon: Icon(Icons.contact_page,),
   label: "버튼 이름"),

BottomNavigationBarItem 을 선언하고, 아이콘의 모양과 설명글을 적어주는 방식이다.
label은 생략 가능하다.

이런식으로 아이템들을 추가해주면 아래처럼 설정이 가능하다.

추가로 넣은 backgroundColor와 fixedColor는 각각 배경색, 클릭시 글자/아이콘색을 의미한다.

Scaffold(
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: _selectedIndex,
          onTap: _onItemTapped,
          items: const [
            BottomNavigationBarItem(
                icon: Icon(
                  Icons.contact_page,
                ),
                label: "첫번째 버튼"),
            BottomNavigationBarItem(
                icon: Icon(
                  Icons.abc_rounded,
                ),
                label: "두번째 버튼"),
            BottomNavigationBarItem(
                icon: Icon(
                  Icons.ac_unit_rounded,
                ),
                label: "세번째 버튼"),
          ],
          backgroundColor: mainColor,
          fixedColor: Colors.white,
        ),
      ),

이제 네비게이션 버튼들은 생성되었으니 각 버튼을 눌렀을 때 이동할 페이지를 만들어보자.

나는 간단하게 아래와 같이 페이지를 만들고 배열에 담았다.
지금 생각해보니 한개만 만들고 변수를 받아서 넣으면 되는데 굳이 3개를 일일히 적은 나 자신을 반성한다.

List test = <Widget>[firstScreenTest(), secondScreenTest(), thirdScreenTest()];


class firstScreenTest extends StatelessWidget {
  const firstScreenTest({super.key});

  @override
  Widget build(BuildContext context) {
    return Text("첫번째 화면");
  }
}

class secondScreenTest extends StatelessWidget {
  const secondScreenTest({super.key});

  @override
  Widget build(BuildContext context) {
    return Text("두번째 화면");
  }
}

class thirdScreenTest extends StatelessWidget {
  const thirdScreenTest({super.key});

  @override
  Widget build(BuildContext context) {
    return Text("세번째 화면");
  }
}

어쨌든 화면은 선언되었고, 이제 우리는 버튼을 눌렀을 때 각 페이지를 볼 수 있도록 설정해야 한다.

_selectedIndex는 어떤 페이지가 선택되었는지 살펴볼 수 있게 하는 int 형의 변수로 선언했다.
그리고 Scoffold 위젯의 body에 우리가 선언한 배열의 값을 담는다.

  int _selectedIndex = 0; //추가한 변수

  @override
  Widget build(BuildContext context) {
	....생략....
    
  Scaffold(
          body: test.elementAt(_selectedIndex),
          bottomNavigationBar: BottomNavigationBar(..생략
        

마지막으로 버튼을 누르면 각각의 페이지로 이동할 수 있도록 선언한다.

  int _selectedIndex = 0;
 
  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index; // 페이지/네비게이션 바 활성화 값 적용
    });
  }

  @override
  Widget build(BuildContext context) {
	....생략....

  bottomNavigationBar: BottomNavigationBar(
      currentIndex: _selectedIndex, //현재 네비게이션 바 활성화된 인덱스
      onTap: _onItemTapped, //클릭시 클릭한 index값을 전달
      items: const [...생략....

3개이상 추가시 하얘지는 현상

충격적이게도 해당 Widget은 3개 이상의 BottomNavigationBarItem을 넣으면 배경이 하얘지는 현상이 발생했다.
알아보니 기본적으로 bottomNavigationBar의 type 속성이 shifting 으로 설정되어 있는데, 이 속성이 3개 이상은 적용되지 않는다고 한다.
그래서 fix로 고치면 해결 가능하다.

아래 속성을 bottomNavigationBar 내부에 집어넣자.

      type: BottomNavigationBarType.fixed,

그럼 버그 해결 완료된다.

끝났다.
전체 소스 보고 마무리하자.

전체 소스 예제

List test = <Widget>[firstScreenTest(), secondScreenTest(), thirdScreenTest()];

class Example extends StatefulWidget {
const Example({super.key});

@override
State<Example> createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
int _selectedIndex = 0;
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}

@override
Widget build(BuildContext context) {
bool backButtonChk = false; //뒤로가기 클릭여부 파악
///뒤로가기 클릭시 Splash 화면으로 넘어가는것을 방지
///더불어 2초 안에 2번 뒤로가기를 누르면 앱 종료 기능 추가
return Scaffold(
body: test.elementAt(_selectedIndex),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onItemTapped,
items: const [
BottomNavigationBarItem(
icon: Icon(
Icons.contact_page,
),
label: "첫번째 버튼"),
BottomNavigationBarItem(
icon: Icon(
Icons.abc_rounded,
),
label: "두번째 버튼"),
BottomNavigationBarItem(
icon: Icon(
Icons.ac_unit_rounded,
),
label: "세번째 버튼"),
],
backgroundColor: mainColor,
fixedColor: Colors.white,
),
);
}
}

class firstScreenTest extends StatelessWidget {
const firstScreenTest({super.key});

@override
Widget build(BuildContext context) {
return Text("첫번째 화면");
}
}

class secondScreenTest extends StatelessWidget {
const secondScreenTest({super.key});

@override
Widget build(BuildContext context) {
return Text("두번째 화면");
}
}

class thirdScreenTest extends StatelessWidget {
const thirdScreenTest({super.key});

@override
Widget build(BuildContext context) {
return Text("세번째 화면");
}
}

profile
재밌게 하고싶다.

0개의 댓글