본문 바로가기

Flutter-플러터/플러터 공부

Flutter - TabBar 사용시 GetxController 중복 사용

반응형

 

Getx에서  GetxController는 아주 중요합니다.

 

Flutter의 setState, onInit 등등 여러가지 주요한 기능들도 수행하기 때문입니다.

 

 

즉 GetxController를 사용하는 페이지가 있다면 앱이 실행되기 전이나, 페이지가 이동 하기 전에 해당 GetxController가 불러져야 합니다.

 

 

기존의 저는 Routers페이지를 만들어서 Bindings를 통해서 GetxController를 생성했습니다. 

하지만  TabBarView를 사용하면서 문제가 발생했습니다.

 

import 'package:get/get.dart';
import 'package:money_tracker_test/controller/calculator/calculator_home_controller.dart';
import 'package:money_tracker_test/controller/calculator/calculator_interestrate_controller.dart';
import 'package:money_tracker_test/controller/calculator/calculator_rent_controller.dart';
import 'package:money_tracker_test/controller/calculator/calculator_vat_controller.dart';
import 'package:money_tracker_test/controller/home/home_tabbar_controller.dart';
import 'package:money_tracker_test/controller/home/money_tracker_controller.dart';
import 'package:money_tracker_test/controller/testpage_controller.dart';
import 'package:money_tracker_test/screen/Calculator/calculator_home_page.dart';
import 'package:money_tracker_test/screen/Calculator/calculator_rent_page.dart';
import 'package:money_tracker_test/screen/Calculator/calculator_vat_page.dart';
import 'package:money_tracker_test/screen/Calculator/claculator_interestrate_page.dart';
import 'package:money_tracker_test/screen/Home/home_tabbar_page.dart';

import 'package:money_tracker_test/screen/Home/money_tracker_page.dart';
import 'package:money_tracker_test/test_page.dart';

class RoutersPages {
  static final routes = [
    GetPage(
        name: '/TestPage',
        page: () => TestPage(),
        fullscreenDialog: true,
        binding: BindingsBuilder(() {
          Get.put<TestPageController>(TestPageController());
        })),
    GetPage(
      name: '/MoneyTrackerPage',
      page: () => MoneyTrackerPage(),
      fullscreenDialog: false,
    ),
    GetPage(
        name: '/CalculatorHomePage',
        page: () => CalculatorHomePage(),
        fullscreenDialog: true,
        binding: BindingsBuilder(() {
          Get.put<CalculatorHomeController>(CalculatorHomeController());
        })),
    GetPage(
        name: '/CalculatorRentPage',
        page: () => CalculatorRentPage(),
        fullscreenDialog: true,
        binding: BindingsBuilder(() {
          Get.put<CalculatorRentController>(CalculatorRentController());
        })),
    GetPage(
        name: '/CalculatorVatPage',
        page: () => CalculatorVatPage(),
        fullscreenDialog: true,
        binding: BindingsBuilder(() {
          Get.put<CalculatorVatController>(CalculatorVatController());
        })),
    GetPage(
        name: '/CalculatorInterestRatePage',
        page: () => CalculatorInterestRatePage(),
        fullscreenDialog: true,
        binding: BindingsBuilder(() {
          Get.put<CalculatorInterestRateController>(
              CalculatorInterestRateController());
        })),
    GetPage(
        name: '/HomeTabbarPage',
        page: () => HomeTabbarPage(),
        fullscreenDialog: true,
        binding: BindingsBuilder(() {
          Get.put<HomeTabBarController>(HomeTabBarController());
        })),
  ];
}

 

 

아래는 TabBarView 페이지 입니다. 

해당 페이지에는 기존에 만들어둔 가계부 페이지가 있습니다. 

즉 가계부 페이지의 GetxController가 앱이 실행 되기 전에 불러와야 합니다. 

 

해서 main.dart 파일에 runMyApp 함수 실행전에 각 컨트롤러를 실행시키는 코드로 개선했습니다. 

 

 

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:money_tracker_test/controller/home/home_tabbar_controller.dart';
import 'package:money_tracker_test/screen/Home/money_tracker_page.dart';
import 'package:money_tracker_test/utils/colors.dart';

class HomeTabbarPage extends GetView<HomeTabBarController> {
  const HomeTabbarPage({super.key});

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 5, // 탭의 개수
      child: Scaffold(
        appBar: AppBar(
          bottom: TabBar(
            tabs: [
              Tab(text: "일별"),
              Tab(text: "달력"),
              Tab(text: "월별"),
              Tab(text: "결산"),
              Tab(text: "메모"),
            ],
          ),
        ),
        drawer: Drawer(
          child: ListView(
            padding: EdgeInsets.zero,
            children: <Widget>[
              const DrawerHeader(
                decoration: BoxDecoration(
                  color: GlobalStyle.green50,
                ),
                child: Text(
                  '사장님이 매일 자람',
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 24,
                  ),
                ),
              ),
              ListTile(
                leading: Icon(Icons.monetization_on),
                title: Text('상가 중개 수수료 계산기'),
                onTap: () {
                  // 부가세 계산기 페이지로 이동
                  Get.toNamed('/CalculatorRentPage');
                  // 드로어 닫기
                },
              ),
              ListTile(
                leading: Icon(Icons.calculate),
                title: Text('음식점 부가세 계산기'),
                onTap: () {
                  // 부가세 계산기 페이지로 이동
                  Get.toNamed('/CalculatorVatPage');
                  // 드로어 닫기
                },
              ),
              ListTile(
                leading: Icon(Icons.percent),
                title: Text('은행 대출 이자 계산기'),
                onTap: () {
                  // 부가세 계산기 페이지로 이동
                  Get.toNamed('/CalculatorInterestRatePage');
                  // 드로어 닫기
                },
              ),
            ],
          ),
        ),
        body: TabBarView(
          children: [
            MoneyTrackerPage(), // 일별 페이지
            Container(), // 달력 페이지
            Container(), // 월별 페이지
            Container(), // 결산 페이지
            Container(), // 메모 페이지
          ],
        ),
      ),
    );
  }
}

 

 

 

메인페이지에 initControllers(); 함수를 만들어서 

lazyput 방법으로 GetxController를 불러왔습니다.  

 

GPT 교수님께 중복으로 컨트롤러를 사용해도 되냐고 문의를 했습니다. 

 

답변은 좋지 않다...였습니다.

 

하지만 기존에 Routers에 있는 bindings으로 생성된 컨트롤러를 삭제하면
앱내에서 해당 페이지로 이동 할 때 GetXController가 불러오지 않는 문제가 또 생겨버립니다.

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:get/route_manager.dart';
import 'package:money_tracker_test/controller/calculator/calculator_home_controller.dart';
import 'package:money_tracker_test/controller/calculator/calculator_interestrate_controller.dart';
import 'package:money_tracker_test/controller/calculator/calculator_rent_controller.dart';
import 'package:money_tracker_test/controller/calculator/calculator_vat_controller.dart';
import 'package:money_tracker_test/controller/home/home_tabbar_controller.dart';
import 'package:money_tracker_test/controller/home/money_tracker_controller.dart';
import 'package:money_tracker_test/controller/testpage_controller.dart';

import 'package:money_tracker_test/utils/colors.dart';
import 'package:money_tracker_test/utils/routers.dart';

void main() {
  initControllers();

  runApp(const MyApp());
}

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return ScreenUtilInit(
        designSize: const Size(360, 690),
        minTextAdapt: true,
        splitScreenMode: true,
        builder: (_, child) {
          return GetMaterialApp(
              theme: ThemeData(
                colorScheme:
                    ColorScheme.fromSeed(seedColor: GlobalStyle.green100),
                useMaterial3: true,
              ),
              initialRoute: "/TestPage",
              getPages: RoutersPages.routes);
        });
  }
}

void initControllers() {
  Get.lazyPut(() => TestPageController());
  Get.lazyPut(() => MoneyTrackerController());
  Get.lazyPut(() => CalculatorHomeController());
  Get.lazyPut(() => CalculatorRentController());
  Get.lazyPut(() => CalculatorVatController());
  Get.lazyPut(() => CalculatorInterestRateController());
  Get.lazyPut(() => HomeTabBarController());
}

 

 

 

 

그래서 그냥 중복으로 GetXController를 사용하기로 했습니다. 

문제가 생기면 또 해결해야죠...후후 

 

 

728x90
반응형