guricode

BottomNavigationBar_Widget 본문

앱/Flutter&Dart

BottomNavigationBar_Widget

agentrakugaki 2025. 8. 4. 23:02

BottomNavigationBar는 Flutter에서 하단 탭바 UI를 구현할 때 사용하는 대표적인 위젯이다. 대표적으로 홈, 검색, 마이페이지 같은 화면 간의 전환을 직관적으로 제공할 수 있다. Android에서는 Bottom Navigation, iOS에서는 탭 바(Tab Bar)와 유사한 개념이다.

Flutter의 BottomNavigationBarScaffoldbottomNavigationBar 프로퍼티에 위치하며, BottomNavigationBarItem 위젯의 리스트로 구성된다. 사용자는 탭을 누름으로써 onTap 콜백을 통해 index 값을 전달받아 현재 페이지 상태를 갱신한다.


기본 사용법

Scaffold(
  body: _pages[_selectedIndex],
  bottomNavigationBar: BottomNavigationBar(
    currentIndex: _selectedIndex,
    onTap: (index) {
      setState(() => _selectedIndex = index);
    },
    items: const [
      BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
      BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Search'),
      BottomNavigationBarItem(icon: Icon(Icons.person), label: 'My'),
    ],
  ),
)

주요 속성

속성 설명
items 하단 탭 항목을 담는 리스트 (BottomNavigationBarItem)
currentIndex 현재 선택된 탭의 인덱스
onTap 탭이 눌렸을 때 호출되는 콜백, index 전달
selectedItemColor 선택된 항목의 색상
unselectedItemColor 선택되지 않은 항목의 색상
type 탭바의 타입 (fixed, shifting)

BottomNavigationBarType

  • fixed: 탭이 3개 이하이거나 동일한 크기로 균등하게 배치되기를 원할 때 사용.
  • shifting: 4개 이상일 때 추천되며, 선택된 아이템만 강조됨.
BottomNavigationBar(
  type: BottomNavigationBarType.fixed,
  ...
)

상태 관리: State vs Riverpod 비교

1. StatefulWidget으로 구현

int _currentIndex = 0;
final _pages = [HomePage(), SearchPage(), MyPage()];
BottomNavigationBar(
  currentIndex: _currentIndex,
  onTap: (index) => setState(() => _currentIndex = index),
  items: [...],
)
  • 장점: 구조가 단순하고 이해하기 쉬움
  • 단점: 전체 앱 구조에서 전역 상태 공유 어려움

2. Riverpod 상태 관리 사용

final bottomNavIndexProvider = StateProvider<int>((ref) => 0);
final index = ref.watch(bottomNavIndexProvider);
ref.read(bottomNavIndexProvider.notifier).state = newIndex;
  • 장점: ViewModel과 연결하기 쉬움, 앱 전체에 걸쳐 상태 공유 가능
  • 단점: 처음 보는 사람에겐 진입장벽 있음

페이지 상태 유지하기

  • 기본적으로 BottomNavigationBar는 페이지를 바꿀 때마다 상태를 잃는다.
  • 이를 방지하려면 IndexedStack을 사용하여 모든 페이지를 메모리에 유지시킬 수 있다.
IndexedStack(
  index: _currentIndex,
  children: [HomePage(), SearchPage(), MyPage()],
)

커스텀 BottomNavigationBar

  • 색상, 폰트 크기, 선택 상태 아이콘 변경 등 다양한 커스터마이징 가능
BottomNavigationBar(
  selectedItemColor: Colors.purple,
  unselectedItemColor: Colors.grey,
  selectedFontSize: 14,
  unselectedFontSize: 12,
  backgroundColor: Colors.white,
  elevation: 8,
)

예외 상황 처리

  • items가 2개 미만이면 오류 발생
  • currentIndex가 범위를 벗어나면 crash 가능
  • type: shifting 일 때 각 itembackgroundColor 설정이 필요함

디자인 UX 팁

  • 탭은 보통 3~5개가 적절함
  • 자주 쓰는 기능을 왼쪽에 배치
  • 현재 탭 강조는 색상과 아이콘 두께로 명확하게 구분
  • 터치 영역은 최소 48px 이상 권장됨

요약

항목 설명
목적 화면 전환을 돕는 하단 탭바 구성
위치 ScaffoldbottomNavigationBar 프로퍼티에 위치
상태 처리 StatefulWidget 또는 Riverpod로 관리 가능
페이지 유지 IndexedStack 사용 권장
커스터마이징 색상, 크기, 배경 등 다양한 설정 가능