[Flutter GetX : 05] 바인딩, 컨트롤러 선언과 사용 간소화

728x90

바인딩, 컨트롤러 선언과 사용 간소화

 

목차
1. 바인딩
2. 컨트롤러 선언, 사용 간소화 예제

1. 바인딩

 ElevatedButton(
              onPressed: () {
                Get.to(
                  () => const GetPut(),
                  binding: BindingsBuilder(() {
                    Get.create<DependencyController>(
                        () => DependencyController());
                  }),
                );
              },
              child: const Text("create")
          ),

바인딩은 페이지 라우트 단계(페이지를 보내는 부분)에서 해당 페이지에서 사용하게 될 컨트롤러를 주입하는 방법이다.

넘어갈 페이지가 어디인지, 어떤 컨트롤러를 주입할 것인지 한번에 지정할 수 있다.

위와 같은 방법으로 BindingsBuilder를 이용해 특정 위젯 내부에 선언해도 상관없으나, 바인딩 부분을 따로 분리하여 GetX로부터 Bindings 인터페이스를 상속받는 방식으로도 구현할 수 있다.

 

(main.dart)

import 'package:flutter/material.dart';
import 'package:flutter_getx/src/controller/count_controller_with_reactive.dart';
import 'package:flutter_getx/src/controller/dependency_controller.dart';
import 'package:flutter_getx/src/home.dart';
import 'package:flutter_getx/src/pages/binding.dart';
import 'package:flutter_getx/src/pages/binding/binding_page.dart';
import 'package:get/get.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      initialRoute: "/",
      getPages: [
        GetPage(name: "/", page: () => const Home()),
        GetPage(
          name: "/binding",
          page: () => const BindingPage(),
          binding: BindingPageBinding()
        ),
      ],
    );
  }
}

(src/home.dart)

import 'package:flutter/material.dart';
import 'package:flutter_getx/src/pages/dependencys/dependency_manage.dart';
import 'package:flutter_getx/src/pages/reactive_state_manage_page.dart';
import 'package:get/get.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("라우트 관리 홈"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
                onPressed: () {
                  Get.toNamed("/binding");
                },
                child: const Text("바인딩"),
            ),
          ]
        )
      )
    );
  }
}

(src/pages/binding.dart) (위에서 선언한 바인딩 버튼을 누르면 넘어갈 페이지)

/binding은 BindingPage() 위젯으로 이동시키는데 그 클래스를 담고 있다.

대충 빈 화면으로 만들어 준다.

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
    );
  }
}

(src/pages/binding/binding_page.dart)

Bindings 인터페이스를 상속받고 컨트롤러의 의존관계를 명시하였다. (저번에 만들었던 컨트롤러를 집어넣었다.)

import 'package:flutter_getx/src/controller/count_controller_with_reactive.dart';
import 'package:get/get.dart';

class BindingPageBinding implements Bindings {
  @override
  void dependencies() {
    Get.put(CountControllerWithReactive());
  }
}

(src/controller/count_controller_with_reactive.dart)

컨트롤러 코드는 확인차 임의로 넣은 것이므로 중요하진 않다.

import 'package:get/get.dart';


class CountControllerWithReactive extends GetxController {
  RxInt count = 0.obs;  // 반응형으로 필드값을 관리할 수 있음.

  void increase() {
    count++;
  }
  void putNumber(int value){
    count(value);
  }
}

버튼을 누르면 /binding으로 이동하고 컨트롤러의 인스턴스가 생성되는 것을 확인할 수 있다. 뒤로가기를 하면 인스턴스가 즉시 삭제될 것이다.

 

 

2. 컨트롤러 선언, 사용 간소화 예제

 

지금까지의 코드를 활용해서 버튼을 누르면 카운트가 되는 예제를 더욱 간단하게 만들 수 있다.

먼저 count_controller_with_reactive.dart를 수정하자.

import 'package:get/get.dart';


class CountControllerWithReactive extends GetxController {
  static CountControllerWithReactive get to => Get.find();
  RxInt count = 0.obs;  // 반응형으로 필드값을 관리할 수 있음.

  void increase() {
    count++;
  }
  void putNumber(int value){
    count(value);
  }
}

컨트롤러 인스턴스를 컨트롤러 클래스 내부에 static으로 선언할 수 있다.

이렇게 하면 다른 곳에서 이 컨트롤러에 find()메서드를 입력하지 않고도 접근할 수 있다.

 

binding.dart를 수정하여 위의 컨트롤러의 count값을 받아오고 버튼을 누르면 count값을 증가시키도록 만들어 보자.

import 'package:flutter/material.dart';
import 'package:flutter_getx/src/controller/count_controller_with_reactive.dart';
import 'package:get/get.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: [
          Obx(
              () => Text(
                controller.count.toString(),
                style: const TextStyle(fontSize: 40),
              ),
          ),
          ElevatedButton(
              onPressed: () {
                controller.increase();
              },
              child: null
          ),
        ]
      )
    );
  }
}
class BindingPage extends GetView<CountControllerWithReactive> {
  const BindingPage({Key? key}) : super(key: key);

StatelessWidget 대신 GetView<사용할 컨트롤러 클래스> 방식으로 코드를 수정했다.

이렇게 하면 이 클래스 내부에서 컨트롤러에 대한 접근을 'controller' 라는 이름으로도 할 수 있게 되며, 귀찮게 타입을 지정하지 않아도 된다!

 

body: Column(
        children: [
          Obx(
              () => Text(
                controller.count.toString(),
                style: const TextStyle(fontSize: 40),
              ),
          ),
          ElevatedButton(
              onPressed: () {
                controller.increase();
              },
              child: null
          ),
        ]
      )

controller라는 이름으로 위에서 만들었던 컨트롤러에 접근할 수 있기 때문에 코드가 굉장히 간결해진다.

다만 obs로 선언했던 값을 Obx로 넣어주지 않으면 에러가 발생하므로 반응형 상태관리 컨트롤러를 이용해야 한다. 

 

 

728x90