티스토리 뷰

0.  소개


이전에 StatefulWidget으로 만들었던 BottomNavigationBar를 GetX controller를 이용해 만들어보겠습니다.

GetX 라이브러리에서는 StatefulWidget 사용을 지양하니 섞어 사용중이시라면 GetX 방식으로 바꾸시는걸 권장드립니다.

 

[Flutter] 하단탭바, BottomNavigationBar 만들기

이거 탭바라고 자주불렀는데, 플러터에선 BottomNavigationBar라고 하네요. 플러터에서 탭바는 상단에 있는 이거라고 합니다. 현재 만들 것은 TabBar가 아닌 BottomNavigationBar 입니다. 시작 1️⃣ BottomNavg..

dokit.tistory.com

이전글

 

 

1. GetX Controller 만들기


// BottomNavigationBar 상태 관리를 위한 GetX controller
class MyBottomNavgationBarController extends GetxController {
  // Get.fine 대신 클래스명 사용 가능
  static MyBottomNavgationBarController get to => Get.find();

  // 현재 선택된 탭 아이템 번호 저장
  final RxInt selectedIndex = 0.obs;

  // 탭 이벤트가 발생할 시 selectedIndex값을 변경해줄 함수
  void changeIndex(int index) {
    selectedIndex(index);
  }
}

BottomNavigationBar 필수 속성인 currentIndex와 onTap에 지정해주기 위한 변수와 함수를 만듭니다.

 

2. BottomNavigationBar class 정의


class MyBottomNavgationBar extends GetView<MyBottomNavgationBarController> {
  const MyBottomNavgationBar({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Obx(() => BottomNavigationBar(
          // 현재 인덱스를 selectedIndex에 저장
          currentIndex: controller.selectedIndex.value,
          // 요소(item)을 탭 할 시 실행)
          onTap: controller.changeIndex,
          // 선택에 따라 icon·label 색상 변경
          selectedItemColor: context.theme.colorScheme.onBackground,
          unselectedItemColor: context.theme.colorScheme.onSurfaceVariant,
          // 선택에 따라 label text style 변경
          unselectedLabelStyle: TextStyle(fontSize: 10),
          selectedLabelStyle: TextStyle(fontSize: 10),
          // 탭 애니메이션 변경 (fixed: 없음)
          type: BottomNavigationBarType.fixed,
          backgroundColor: context.theme.colorScheme.background,
          // Bar에 보여질 요소. icon과 label로 구성.
          items: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
                icon: controller.selectedIndex.value ==
                        0 // 선택된 탭은 채워진 아이콘, 나머지는 line 아이콘
                    ? SvgPicture.asset(
                        'assets/icons/menu1_solid.svg',
                      )
                    : SvgPicture.asset(
                        'assets/icons/menu1_line.svg',
                      ),
                label: "tap1"),
            BottomNavigationBarItem(
                icon: controller.selectedIndex.value == 1
                    ? SvgPicture.asset(
                        'assets/icons/menu2_solid.svg',
                      )
                    : SvgPicture.asset(
                        'assets/icons/menu2_line.svg',
                      ),
                label: "tap2"),
            BottomNavigationBarItem(
                icon: controller.selectedIndex.value == 2
                    ? SvgPicture.asset(
                        'assets/icons/menu3_solid.svg',
                      )
                    : SvgPicture.asset(
                        'assets/icons/menu3_line.svg',
                      ),
                label: "tap3"),
          ],
        ));
  }
}

GetView를 통해 controller라는 키워드로 MyBottomNavgationBarController에 접근할 수 있습니다.

또, BottomNavigationBar를 Obx로 감싸 선택된 탭이 채워진 아이콘으로 변경될 수 있게 하였습니다. (Obx 내부에 변경 값이 있는지 감시)

 

3. Scaffold 정의


class RootScaffold extends StatelessWidget{

  // 탭별 화면
  static List<Widget> tabPages = <Widget>[
    Page1(), // 외부 클래스로 정의
    Page2(),
    Page3(),
  ];

  @override
  Widget build(BuildContext context) {

    // 페이지 전환을 위한 MyBottomNavgationBarController 인스턴스화 (의존성 주입)
    // Get.put : 수명이 페이지와 같음
    Get.put(MyBottomNavgationBarController());

    return Scaffold(
      backgroundColor: context.theme.colorScheme.background,
      // 빈 AppBar 따로 정의
      appBar: EmptyAppBar(),
      // MyBottomNavgationBarController의 변수가 변하면 화면(페이지) 변경
      body: Obx(() => SafeArea(
          child:
              // static 변수를 이용해 컨트롤러 접근
              tabPages[MyBottomNavgationBarController.to.selectedIndex.value])),
       // 2번에서 만든 BottomNavgationBar 컴포넌트
      bottomNavigationBar: MyBottomNavgationBar(),
    );
  }
}

각 탭별 페이지 컴포넌트를 정의하고 컨트롤러에 저장한 인덱스를 통해 탭별로 맞는 화면을 body 부분에 보여줍니다.

 

 

 

 


감사합니다.

 

Ref.

 

[j Flutter] Getx 사용해 BottomNavigationBar 만들기

1. GetView  사용하기 class App extends GetView { @override Widget build(BuildContext context) { return Scaffold( body: Obx(() { switch (RouteName.values[controller.currentIndex.value]) { case Route..

yj95.tistory.com

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함