개발노트

77. [Flutter] GetX 의 Named Route 사용하여, 화면 전환되는bottomNavigationBar만들기 본문

앱 개발/Flutter

77. [Flutter] GetX 의 Named Route 사용하여, 화면 전환되는bottomNavigationBar만들기

mroh1226 2024. 8. 8. 00:34
반응형

GetXanimated_bottom_navigation_bar 을 이용하여 하단탭 페이지전환 기능 만들기.!

만들면서 Named Route 사용법을 익혀본다.

 

GetX 설치: https://pub.dev/packages/get/install

 

get install | Flutter package

Open screens/snackbars/dialogs without context, manage states and inject dependencies easily with GetX.

pub.dev

하단Navigation버튼 바: https://pub.dev/packages/animated_bottom_navigation_bar

 

animated_bottom_navigation_bar | Flutter package

Animated Bottom Navigation Bar Widget implementation inspired by https://dribbble.com/shots/7134849-Simple-Tab-Bar-Animation

pub.dev


 

1. main.dart 에 MaterialApp 을 GetMaterialApp으로 변경한다.

main.dart
import 'package:flutter/material.dart';
import 'package:flutter_application_sub/router.dart';
import 'package:get/get_navigation/src/root/get_material_app.dart';

void main() {
  runApp(const MainApp());
}

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

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      initialRoute: '/',
      getPages: Routes.pages,
    );
  }
}

 


2. App 화면 간의 네비게이션으로 사용될 route를 따로 관리하기 위해 아래 파일 생성

router.dart
import 'package:flutter_application_sub/navigation_page.dart';
import 'package:flutter_application_sub/pages/explore_page.dart';
import 'package:flutter_application_sub/pages/inbox_page.dart';
import 'package:flutter_application_sub/pages/profile_page.dart';
import 'package:flutter_application_sub/pages/trips_page.dart';
import 'package:flutter_application_sub/pages/wishlist_page.dart';
import 'package:get/get_navigation/src/routes/get_route.dart';
import 'package:get/get.dart';

class Routes {
  static List<GetPage> pages = [
    GetPage(
      name: '/',
      page: () => const NavigationPage(),
    ),
    GetPage(
      name: '/explore',
      page: () => const ExplorePage(),
    ),
    GetPage(
      name: '/inbox',
      page: () => const InboxPage(),
      transition: Transition.downToUp,//전환 애니메이션
    ),
    GetPage(
      name: '/profile',
      page: () => const ProfilePage(),
    ),
    GetPage(
      name: '/trips',
      page: () => const TripsPage(),
    ),
    GetPage(
      name: '/wishlist',
      page: () => const WishlistPage(),
    ),
  ];
}

 

3. 이제 GetBuilder를 통해 Controller를 LazyPut하고, 하단바 버튼을 클릭했을 때,

indexedStack과 Controller의 index를 이용하여 페이지 전환을 만들어본다.

navigation_page.dart
import 'package:animated_bottom_navigation_bar/animated_bottom_navigation_bar.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_application_sub/pages/explore_page.dart';
import 'package:flutter_application_sub/pages/inbox_page.dart';
import 'package:flutter_application_sub/pages/profile_page.dart';
import 'package:flutter_application_sub/pages/trips_page.dart';
import 'package:flutter_application_sub/pages/wishlist_page.dart';
import 'package:get/get.dart';

// NavigationPage 클래스: 전체 네비게이션과 페이지 관리를 담당합니다.
class NavigationPage extends StatelessWidget {
  const NavigationPage({super.key});

  @override
  Widget build(BuildContext context) {
    // NaviController를 GetX를 통해 의존성 주입합니다.
    Get.lazyPut(() => NaviController());

    return GetBuilder<NaviController>(
      builder: (controller) {
        return Scaffold(
          // IndexedStack: 현재 선택된 페이지를 표시합니다. 인덱스에 따라 페이지가 전환됩니다.
          body: Center(
            child: IndexedStack(
              index: controller.selectedIndex, // 현재 선택된 페이지 인덱스
              children: const [
                ExplorePage(),
                TripsPage(),
                ProfilePage(),
                WishlistPage(),
              ],
            ),
          ),
          // FloatingActionButton 위치 설정
          floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
          // FloatingActionButton: InboxPage로 전환하는 버튼
          floatingActionButton: FloatingActionButton(
            shape: const CircleBorder(), // 버튼을 원형으로 설정
            backgroundColor: Colors.orange,
            child: const Icon(
              Icons.inbox,
              color: Colors.white,
            ),
            onPressed: () {
              // 페이지 전환: GetX를 사용하여 InboxPage로 이동
              Get.to(() => const InboxPage());
            },
          ),
          // AnimatedBottomNavigationBar: 하단 네비게이션 바 설정
          bottomNavigationBar: AnimatedBottomNavigationBar(
            backgroundColor: const Color.fromARGB(255, 55, 29, 150),
            gapLocation: GapLocation.center, // 아이콘 사이 간격 위치
            notchSmoothness: NotchSmoothness.verySmoothEdge,
            rightCornerRadius: 32,
            leftCornerRadius: 32,
            icons: const [
              Icons.explore,
              Icons.airplanemode_active,
              Icons.person,
              Icons.list,
            ],
            activeIndex: controller.selectedIndex, // 현재 활성화된 아이콘 인덱스
            activeColor: Colors.amber, // 활성화된 아이콘 색상
            onTap: (index) {
              // 클릭된 아이콘 인덱스를 NaviController에 설정
              controller.setIndex(index);
            },
          ),
        );
      },
    );
  }
}

// NaviController 클래스: 현재 선택된 페이지의 인덱스를 관리합니다.
class NaviController extends GetxController {
  var selectedIndex = 0; // 현재 선택된 페이지 인덱스

  // 선택된 페이지 인덱스를 설정하고 UI를 업데이트합니다.
  void setIndex(int index) {
    selectedIndex = index;
    update();
  }
}

 

완성

반응형
Comments