본문 바로가기

Flutter/07 State - Getx

[Flutter] Getx - Binding

이번 카테고리는 GetX 의 dependency injection 의 다양한 binding 방법에 대해서 알아보겠습니다.

개발환경 : 윈도우11, 안드로이드 스튜디오, flutter 3.0.1

소스코드 위치 - Release 12_getx_binding · mike-bskim/getx_test · GitHub

 

Release 12_getx_binding · mike-bskim/getx_test

 

github.com

 

프로젝트 구조

main.dart

/src/home.dart

/src/bindings/binding_injection.dart

/src/controller/dependency_controller.dart

/src/pages/binding/binding_page.dart

 

binding_injection.dart - 여러개의 GetxController 를 한번에 injection 가능

 

import 'package:get/get.dart';
import '../controller/dependency_controller.dart';

class BindingInjection implements Bindings {
  @override
  void dependencies() {
    Get.put(DependencyController());
    ...
    ...
  }
}

 

main.dart - 아래 부분이 추가됨

 

GetPage(
    name: '/binding',
    page: () => const BindingPage(),
    // BindingsBuilder 를 통해서 dependency injection.
    binding: BindingsBuilder(() {
      Get.put(DependencyController());
    }),
    transition: Transition.fadeIn),

또는 

GetPage(
    name: '/binding',
    page: () => const BindingPage(),
    // 클래스를 통해서 dependency injection.
    binding: BindingInjection(),
    transition: Transition.fadeIn),

 

home.dart - 아래 부분 추가됨

 

ElevatedButton(
  style: elevatedButtonStyle,
  child: const Text("바인딩 관리"),
  onPressed: () {
    Get.toNamed('/binding');
  },
),

 

binding_page.dart - 해시코드 출력 및 count 증가, 화면에 count 표시

 

import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../controller/dependency_controller.dart';

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

  @override
  Widget build(BuildContext context) {
    var textStyle = const TextStyle(fontSize: 20);

    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: const Text("Binding"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Obx(() {
            // reactive 방식으로 접근 예시
              return Text('count: ${Get.find<DependencyController>().count.value}',
                  style: textStyle);
            }),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                debugPrint(
                    Get.find<DependencyController>().hashCode.toString());
                 // dependency_controller.dart 파일에 
                 // "static DependencyController get to => Get.find();" 추가해서
                 // 직접 접근 및 Get.find 로 접근 둘다 가능함
                // Get.find<DependencyController>().increase();
                DependencyController.to.increase();
              },
              child: const Text('Print hashCode'),
            ),
          ],
        ),
      ),
    );
  }
}

 

dependency_controller.dart

 

import 'package:flutter/foundation.dart';
import 'package:get/get.dart';

class DependencyController extends GetxController {
  static DependencyController get to => Get.find();
  // Get.find<> 생략하는 방법
  // Get.find<DependencyController>().increase()
  // => DependencyController.to.increase();

  RxInt count=0.obs;
  void increase() {
    count++;
  }

  @override
  void onClose() {
    // 종료시 반환되는 해시코드를 출력
    debugPrint(hashCode.toString());
    super.onClose();
  }
}

 


 

GetX Controller를 injection 하는 2가지 방법.

 

1. GetPage 에서 설정(직접 설정/Bindings 를 통한 설정 예시)

 

// 직접 설정 - GetPage 에서 BindingsBuilder 를 통해서 직접 주입하는 방법
GetPage(
    name: '/binding',
    page: () => const BindingPage(),
    binding: BindingsBuilder(() {
      Get.put(DependencyController());
    }),
    transition: Transition.fadeIn),

 

// Bindings 를 통한 설정 - 클래스를 만들어서 여러 컨트롤러를 한번에 주입하는 방법
class BindingInjection implements Bindings {
  @override
  void dependencies() {
    Get.put(DependencyController());
  }
}
GetPage(
    name: '/binding',
    page: () => const BindingPage(),
    binding: BindingInjection(),
    transition: Transition.fadeIn),

 

2. Get.to 에서 설정(직접 설정)

 

Get.to(
  () => const GetPut(),
  binding: BindingsBuilder(() {
    // 페이지 이동과 동시에 Controller 인스턴스 생성.
    Get.put(DependencyController());
  }),
);

 

 

 

Get.find<> 생략하는 방법 - dependency_controller.dart 초기부분 참고

 

class DependencyController extends GetxController {
  static DependencyController get to => Get.find();
  // Get.find<> 생략하는 방법
  // Get.find<DependencyController>().increase()
  // => DependencyController.to.increase();

 

다른 방식의 Get.find<> 생략하는 방법 - 상위 위젯에서 injection 된 경우 하위 위젯에서 접근 가능

2022.06.09 - [Flutter/07 Getx] - [Flutter] GetX - Get.create 예시

 

[Flutter] GetX - Get.create 예시

이번 카테고리는 GetX 의 Get.create 의 사용 예시에 대해서 알아보겠습니다. 개발환경 : 윈도우11, 안드로이드 스튜디오, flutter 3.0.1 소스코드 위치 - Release 15_Get_create_example2 · mike-bskim/getx_tes..

unsungit.tistory.com

import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../controller/shopping_controller.dart';

class ShoppingItem extends StatelessWidget {
  final String item;
  ShoppingItem({Key? key, required this.item}) : super(key: key);

  // injected by Get.create
  final ShoppingController controller = Get.find();
  // injected by Get.put
  final ShoppingController controllerTotal = Get.find(tag: 'total');

 

 

GetWidget/GetView 로 처리하는 방법

두개는 매우 비슷하지만 다른점은 injection 방식에 따라 주의해서 사용해야 한다.

injection 방식을 Get.create 로 하는 경우에는 차이가 있다. 다른 방식으로 injection 할때는 차이가 없다.

GetWidget - 인스턴스가 한번만 생성된다.

GetView - 인스턴스에 접근할때 마다 새로운 인스턴스가 생성된다.

 

./src/pages/dependencys/get_create.dart 파일의 GetCreateBody 클래스 참고.

 

// class GetCreateBody extends StatelessWidget {
// 아래처럼 변경
class GetCreateBody extends GetWidget<DependencyController> {
  final String _title;
  const GetCreateBody(this._title, {Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(_title, style: const TextStyle(fontSize: 20)),
          Container(
            height: 10,
          ),
          Obx(() {
            return Text(
              // "${Get.find<DependencyController>().count}",
              // 아래처럼 controller 통해서 접근 가능
              "${controller.count}",
              style: const TextStyle(fontSize: 15),
            );
          }),
          ElevatedButton(
            child: const Text("Get.create"),
            onPressed: () {
              debugPrint(
                  'hashCode: ${controller.hashCode} / ${controller.count}');
              controller.increase();
            },
          ),
        ],
      ),
    );
  }
}

 

GetWidget의 콘솔로그

 

I/flutter (20630): hashCode: 115484068 / 0
I/flutter (20630): hashCode: 115484068 / 1
I/flutter (20630): hashCode: 115484068 / 2
I/flutter (20630): hashCode: 115484068 / 3
I/flutter (20630): hashCode: 115484068 / 4

 

GetView 로 처리한 경우

 

// class GetCreateBody extends StatelessWidget {
// 아래처럼 변경
class GetCreateBody extends GetView<DependencyController> {
  final String _title;
  const GetCreateBody(this._title, {Key? key}) : super(key: key);

 

콘솔 로그 - 해쉬값이 계속변경되는것을 볼수 있다.

 

I/flutter (20630): hashCode: 477233000 / 0
[GETX] Instance "DependencyController" has been initialized
[GETX] Instance "DependencyController" has been initialized
I/flutter (20630): hashCode: 299144719 / 0
[GETX] Instance "DependencyController" has been initialized
[GETX] Instance "DependencyController" has been initialized
I/flutter (20630): hashCode: 1001581865 / 0
[GETX] Instance "DependencyController" has been initialized
[GETX] Instance "DependencyController" has been initialized
[GETX] Instance "DependencyController" has been initialized
I/flutter (20630): hashCode: 929454453 / 0
[GETX] Instance "DependencyController" has been initialized
[GETX] Instance "DependencyController" has been initialized
[GETX] Instance "DependencyController" has been initialized

 

 

 

 

 

[참고자료] 유투브 - 개발하는 남자.