ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Widget의 개념과 getX 시작하기
    카테고리 없음 2025. 1. 11. 15:25

    Widget이란?

    flutter는 모든 것이 Widget으로 이루어져 있습니다. Java에서 모든 객체가 Object라는 클래스를 상속 받는 것처럼 flutter에서 UI와 관련된 모든 것은 Widget입니다. 화면 역시 두가지의 Widget으로 분류할 수 있습니다.

    1. StatelessWidget
    2. 변하지 않는 정적인 화면을 구성할 때 사용합니다. 단순 텍스트나 앱에 대한 정보 화면 등이 이 경우에 해당합니다. StatefulWidget보다 성능이 좋습니다.
    3. StatefulWidget
    4. 화면에 변화가 있는 동적인 화면을 구성할 때 사용합니다. 체크박스나 라디오박스, 사용자가 텍스트를 입력하는 필드, 게임의 점수 등 실시간으로 업데이트되는 UI가 포함된 화면의 경우 StatefulWidget을 사용하게 됩니다.

    상태 관리란?

    상태 관리는 UI에서 실시간으로 변하는 여러 데이터들의 상태를 효율적으로 관리하기 위한 개념입니다. 상태 관리가 필요한 이유는 두가지가 있습니다.

    1. 특정 데이터가 바뀔 때 마다 화면 전체를 재 렌더링 하기에는 애플리케이션에서의 자원의 낭비가 너무 크다.
    2. 특정 데이터가 바뀔 때 다른 화면에서도 해당 데이터의 변화가 동일하게 이루어져야 하는 경우가 있다.

    상태 관리 기술을 사용하게 되면 1번처럼 실시간으로 변화하는 데이터에 대한 처리와 2번처럼 여러 컴포넌트에서 공통적으로 사용하는 데이터의 동기화를 아주 쉽고 효율적으로 해결할 수 있습니다.

    GetX 설치하기

    flutter에서 상태 관리 라이브러리는 GetX를 주로 사용합니다.

    GetX를 사용하기 위해서는 pubspec.yaml 파일에 GetX를 추가하고 상단의 pub get만 입력하면 됩니다.

    또 main.dart에 다음만 import해주면 준비가 끝납니다.

    import 'package:get/get.dart';
    

    GetX 사용법

    GetX를 통한 상태 관리 방식은 크게 두가지가 있습니다.

    1. 단순 상태 관리
    2. 반응형 상태 관리

    그 차이는 반응형 상태 관리의 경우 데이터에 변화가 있을 때만 재랜더링을 하게 되는 반면에 단순 상태 관리는 기존의 데이터와 변경되는 데이터가 같은지 확인하지 않습니다. 또 반응형 상태 관리는 workers라는 추가 기능도 있습니다. 코드로 확인해보겠습니다.

    1. 단순 상태 관리

    • 반드시 update 메소드를 통해 화면을 리빌드시키는 작업을 해주어야 합니다.
    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    class Controller extends GetxController {
      int _count = 0;
      int get count => _count;
    
      void increment() {
        _count++;
        update();
      }
    }
    
    final Controller controller = Get.put(Controller());
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      MyApp({super.key});
    
      final controller = Get.put(Controller());
    
      @override
      Widget build(BuildContext context){
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(),
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  GetBuilder<Controller>(
                      builder: (_) => Text(
                        'Current Counter : ${controller.count}',
                        style: const TextStyle(fontSize: 20),
                      )),
                  const SizedBox(height: 24),
                  ElevatedButton(
                      onPressed: () => controller.increment(),
                      child: const Text(
                        'Increase',
                        style: TextStyle(fontSize: 24),
                      ))
                ],
              )
            )
          )
        );
      }
    }
    

    Increase 버튼을 누르면 페이지가 새로 고침 되지 않아도 update됩니다.

    2. 반응형 상태 관리

    이것이 더 많이 사용됩니다.

    반응형 상태 관리에서 데이터를 실시간으로 반영하는 방식에는 두가지가 있습니다.

    1. GetX() - GetX() 아래의 모든 위젯은 controller에서 변경되는 데이터를 실시간으로 반영할 수 있는 상태가 됩니다. controller.counter.value (단순 상태 관리와 다르게 .value 를 추가해 주어야 합니다) 는 controller의 변수를 실시간으로 반영하게 되고 controller.increase()는 controller의 counter 데이터를 실시간으로 증가시키게 됩니다.
    2. Obx() - Obx() 아래의 모든 위젯은 GetX()와 마찬가지로 controller에서 변경되는 데이터를 실시간으로 반영할 수 있는 상태가 됩니다. 사용 방식은 거의 동일하지만 차이가 있다면 GetX()와 달리 controller의 이름을 지정할 수가 없어서 Get.find() 방식으로 접근해야 합니다.
    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    void main() {
      runApp(MaterialApp(
        home: MyHomePage(),
      ));
    }
    
    class MyHomePage extends StatelessWidget {
      MyHomePage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        Get.put(SimpleController()); // 단순 상태 관리 controller 등록
        Get.put(ReactiveController()); // 반응형 상태 관리 controller 등록
        return Scaffold(
          appBar: AppBar(
            title: const Text("단순 / 반응형 상태관리"),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                GetBuilder<SimpleController>( // 단순 상태 관리
                  builder: (controller) {
                    return ElevatedButton(
                      child: Text(
                        '[단순]현재 숫자: ${controller.counter}',
                      ),
                      onPressed: () {
                        controller.increase();
                        // Get.find<SimpleController>().increase();
                      },
                    );
                  },
                ),
                GetX<ReactiveController>( // 반응형 상태관리 - 1
                  builder: (controller) {
                    return ElevatedButton(
                      child: Text(
                        '반응형 1 / 현재 숫자: ${controller.counter.value}', // .value 로 접근
                      ),
                      onPressed: () {
                        controller.increase();
                        // Get.find<ReactiveController>().increase();
                      },
                    );
                  },
                ),
                Obx( // 반응형 상태관리 - 2
                      () {
                    return ElevatedButton(
                      child: Text(
                        '반응형 2 / 현재 숫자: ${Get.find<ReactiveController>().counter.value}', // .value 로 접근
                      ),
                      onPressed: () {
                        Get.find<ReactiveController>().increase();
                      },
                    );
                  },
                ),
              ],
            ),
          ),
        );
      }
    }
    
    //단순 상태 관리를 위한 Controller
    class SimpleController extends GetxController {
      int counter = 0;
    
      void increase() {
        counter++;
        update();
      }
    }
    
    //반응형 상태 관리를 위한 Controller
    class ReactiveController extends GetxController {
      //obs는 observable의 약자로, 오브젝트의 변화를 감지하겠다는 의미이다.
      RxInt counter = 0.obs;
    
      void increase() {
        counter++;
      }
    }
    

    버튼을 누르면 숫자가 바로 업데이트됩니다.

    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    class Controller extends GetxController {
      int _count = 0;
      int get count => _count;
    
      void increment() {
        _count++;
        update();
      }
    }
    
    final Controller controller = Get.put(Controller());
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      MyApp({super.key});
    
      final controller = Get.put(Controller());
    
      @override
      Widget build(BuildContext context){
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(),
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  GetBuilder<Controller>(
                      builder: (_) => Text(
                        'Current Counter : ${controller.count}',
                        style: const TextStyle(fontSize: 20),
                      )),
                  const SizedBox(height: 24),
                  ElevatedButton(
                      onPressed: () => controller.increment(),
                      child: const Text(
                        'Increase',
                        style: TextStyle(fontSize: 24),
                      ))
                ],
              )
            )
          )
        );
      }
    }
    

    Increase 버튼을 누르면 페이지가 새로 고침 되지 않아도 update됩니다.

    2. 반응형 상태 관리

    이것이 더 많이 사용됩니다.

    반응형 상태 관리에서 데이터를 실시간으로 반영하는 방식에는 두가지가 있습니다.

    1. GetX() - GetX() 아래의 모든 위젯은 controller에서 변경되는 데이터를 실시간으로 반영할 수 있는 상태가 됩니다. controller.counter.value (단순 상태 관리와 다르게 .value 를 추가해 주어야 합니다) 는 controller의 변수를 실시간으로 반영하게 되고 controller.increase()는 controller의 counter 데이터를 실시간으로 증가시키게 됩니다.
    2. Obx() - Obx() 아래의 모든 위젯은 GetX()와 마찬가지로 controller에서 변경되는 데이터를 실시간으로 반영할 수 있는 상태가 됩니다. 사용 방식은 거의 동일하지만 차이가 있다면 GetX()와 달리 controller의 이름을 지정할 수가 없어서 Get.find() 방식으로 접근해야 합니다.
    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    void main() {
      runApp(MaterialApp(
        home: MyHomePage(),
      ));
    }
    
    class MyHomePage extends StatelessWidget {
      MyHomePage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        Get.put(SimpleController()); // 단순 상태 관리 controller 등록
        Get.put(ReactiveController()); // 반응형 상태 관리 controller 등록
        return Scaffold(
          appBar: AppBar(
            title: const Text("단순 / 반응형 상태관리"),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                GetBuilder<SimpleController>( // 단순 상태 관리
                  builder: (controller) {
                    return ElevatedButton(
                      child: Text(
                        '[단순]현재 숫자: ${controller.counter}',
                      ),
                      onPressed: () {
                        controller.increase();
                        // Get.find<SimpleController>().increase();
                      },
                    );
                  },
                ),
                GetX<ReactiveController>( // 반응형 상태관리 - 1
                  builder: (controller) {
                    return ElevatedButton(
                      child: Text(
                        '반응형 1 / 현재 숫자: ${controller.counter.value}', // .value 로 접근
                      ),
                      onPressed: () {
                        controller.increase();
                        // Get.find<ReactiveController>().increase();
                      },
                    );
                  },
                ),
                Obx( // 반응형 상태관리 - 2
                      () {
                    return ElevatedButton(
                      child: Text(
                        '반응형 2 / 현재 숫자: ${Get.find<ReactiveController>().counter.value}', // .value 로 접근
                      ),
                      onPressed: () {
                        Get.find<ReactiveController>().increase();
                      },
                    );
                  },
                ),
              ],
            ),
          ),
        );
      }
    }
    
    //단순 상태 관리를 위한 Controller
    class SimpleController extends GetxController {
      int counter = 0;
    
      void increase() {
        counter++;
        update();
      }
    }
    
    //반응형 상태 관리를 위한 Controller
    class ReactiveController extends GetxController {
      //obs는 observable의 약자로, 오브젝트의 변화를 감지하겠다는 의미이다.
      RxInt counter = 0.obs;
    
      void increase() {
        counter++;
      }
    }
    

    버튼을 누르면 숫자가 바로 업데이트됩니다.

Designed by Tistory.