본문 바로가기

Flutter

[Flutter] Getx 상태관리(2) Get.find()

지난 예제를 통해서 Flutter 의 기본 프로그램인 더하기 프로그램을 Getx 를 통해서 변경해 보았습니다.

 

https://alsmaker.tistory.com/33

 

[Flutter] GetX 상태관리(1) - GetxController, Get.put()

Flutter 에서 GetX 패키지는 이제 정말 없어서 안될 패키지인것 같습니다. GetX에서 가장 많이 사용하는 기능은 크게 상태관리와 Routing일 것 같습니다. GetX 에 대한 자세한 정보는 아래 링크에서 보시

alsmaker.tistory.com

 

하지만 단일 페이지의 프로그램은 존재할 수가 없겠죠.

이제 단일 페이지가 아니라 Routing 을 통해서 다른 페이지로 이동하는 경우에 사용했던 Controller 를 어떻게 활용할지 알아보겠습니다.

우리가 만들 앱은 아래와 같이 이동한다고 가정해 보겠습니다.

 

 

우선 그동안의 싱글페이지가 아닌 Routing 이 가능한 앱으로 변경해 보겠습니다.

저는 MaterialApp보다 Getx의 라우팅 기능을 편하게 사용할 수 있는 GetMaterialApp으로 시작해보겠습니다.

 

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
        title: 'Flutter Demo',
        initialRoute: '/',
        getPages: [
          GetPage(name: '/', page: () => const Home()),
          GetPage(name: '/route_one', page: () => RouteOne()),
          GetPage(name: '/route_two', page: () => RouteTwo()),
        ]
    );
  }
}

 

Getx의 라우팅 기능은 다시 한번 포스팅을 통해 자세히 알아보도록 하겠습니다.

일단 오늘은 GetMaterialApp이 이렇게 동작한다는 것만 알아두시면 될 것 같습니다.

 

제가 작업한 폴더의 구조는 다음과 같습니다.

 

 

initailRoute 는 Home 이라는 클래입니다.

따라서 이앱의 첫페이지는 Home 이라는 클래스부터 시작합니다.

 

 

이제 Home 에서 route_one이라는 첫번째 라우트로 이동해 보겠습니다.

 

class RouteOne extends StatelessWidget {
  RouteOne({Key? key}): super(key: key);

  final MyController controller = Get.put(MyController());
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Route One'),
      ),
      body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Text('Page One',
                style: TextStyle(fontSize: 40),),
              const SizedBox(height: 20,),
              Obx(() => Text(
                controller.myNumber.value.toString(),
                style: const TextStyle(fontSize: 50),
              ),
              ),
              const SizedBox(height: 20),
              GestureDetector(
                onTap: () {
                  controller.plus();
                },
                child: Container(
                  margin: const EdgeInsets.fromLTRB(15, 0, 10, 0),
                  padding: const EdgeInsets.all(10),
                  child: const Text('PLUS',
                    style: TextStyle(fontSize: 20),),
                  decoration: const BoxDecoration(
                      color: Colors.blue,
                      borderRadius: BorderRadius.all(Radius.circular(10))
                  ),
                ),
              ),
              const SizedBox(height: 20,),
              ElevatedButton(
                  onPressed: () {
                    Get.toNamed('/route_two');
                  },
                  child: const Text('Go to route_two')),
              const SizedBox(height: 20,),
              ElevatedButton(
                  onPressed: () {
                    Get.back();
                  },
                  child: const Text('Go to Home'))
            ],
          )
      ),
    );
  }
}

 

지난번에 Getx controller를 사용하는 페이지를 route_one 으로 이동시켰습니다.

Route One 은 Get.put()을 통해 controller 를 주입하고 있습니다.

그리고 다음페이지 또는 home으로 이동하는 버튼을 가지고 있습니다.

 

 

결과 화면입니다. Plus 를 통해서 현재 값을 '6'으로 변경해 두었습니다.

디버그 화면으로 보면 MyController 가 주입된 것을 볼 수 있습니다.

controller가 생성되는 시점을 알 수 있습니다.

GetMaterialApp을 사용하면 현재 route와 사용중인 controller 를 볼 수 있는 장점이 있습니다.

 

 

이제 route_two로 이동해 보겠습니다.

route_two 는 Get.fine()를 통해 제가 주입해 놓은 controller 를 쉽게 찾을 수 있습니다.

 

 

route_one을 통해 변경해 놓은 '6'의 값을 그대로 사용할 수 있습니다.

아래 코드를 보시면 Get.find() 통해 MyController 를 찾은후에 controller 접근할 수 있습니다.

 

class RouteTwo extends StatelessWidget {
  RouteTwo({Key? key}): super(key: key);

  final MyController controller = Get.find();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Route Two'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('Controller Value',
              style: TextStyle(fontSize: 30),),
            const SizedBox(height:  20,),
            Obx(() => Text(
              controller.myNumber.value.toString(),
              style: const TextStyle(fontSize: 50),),
            ),
            ElevatedButton(
                onPressed: () {
                  Get.back();
                },
                child: const Text('return to route_one'))
          ],
        ),
      ),
    );
  }
}

 

그럼 우리가 만든 controller는 언제 소멸이 될까요?

정답은 controller 를 만든 route가 삭제될때 소멸됩니다.

 

이것을 확인하기 위해 다시 route_one으로 이동한 후 'Go to home'을 통해 home으로 이동해 보겠습니다.

 

Home으로 이동

 

 

controller를 만들었던 route_one이 닫히면서 MyController로 자동적으로 삭제되면서 memory에서도 자동으로 삭제되는 것을 볼 수 있습니다.

내용은 어렵지 않지만 설명만 긴 Getx 의 상태관리를 알아보았습니다.

다음 예제는 Getx 의 상태관리를 통해 BottomNavigationBar 를 사용하는 실전에서 사용할 만한 예제를 적용해 보겠습니다.