Flutter Pub Collection
[ GetX ]
Flutter 패키지

소개

Flutter를 위한 초경량 고성능 상태 관리, 의존성 주입, 라우트 관리 솔루션

설치

pub.dev: https://pub.dev/packages/get

$ flutter pub add get
import 'package:get/get.dart';

1. 반응형 상태 관리

.obs와 Obx()만으로 간단한 반응형 UI 구현. setState() 불필요.

// Controller
var count = 0.obs;
void increment() => count++;

// UI
Obx(() => Text('${count}'))

2. 라우트 관리

Context 없이 어디서든 화면 이동 가능. Navigator 불필요.

Get.to(NextScreen());
Get.back();
Get.offAll(HomePage());  // 모든 이전 화면 제거

3. 의존성 주입

자동 메모리 관리. 화면이 닫히면 자동으로 컨트롤러 제거.

// 등록
Get.put(Controller());

// 사용
final c = Get.find<Controller>();

4. Dialog & Snackbar

BuildContext 없이 어디서든 호출 가능.

Get.snackbar('Title', 'Message');
Get.defaultDialog(title: 'Alert');

5. 실전 예제: 로그인

상태관리 + 라우팅 + Dialog를 한 번에 처리.

class AuthController extends GetxController {
  var isLoggedIn = false.obs;

  void login() async {
    var result = await loginAPI();
    if (result) {
      isLoggedIn(true);
      Get.offAll(HomePage());
      Get.snackbar('Success', 'Login OK');
    }
  }
}

6. GetBuilder vs Obx

GetBuilder는 수동 update(), Obx는 자동 반응형. 용도에 맞게 선택.

// GetBuilder - 수동 업데이트
GetBuilder<CountController>(
  builder: (controller) => Text('${controller.count}'),
)
controller.count++;
controller.update(); // 수동 호출 필요

// Obx - 자동 반응형
Obx(() => Text('${controller.count.value}'))
controller.count++; // 자동 업데이트

7. Get.lazyPut으로 지연 로딩

컨트롤러를 필요할 때까지 생성하지 않음. 메모리 최적화.

// 즉시 생성
Get.put(HeavyController());

// 지연 로딩 - 처음 사용 시 생성
Get.lazyPut(() => HeavyController());

// 사용
final controller = Get.find<HeavyController>();
// 이 시점에 생성됨

8. 메모리 누수 방지

onClose()에서 리소스 정리. Stream, Timer 등 수동 취소 필수.

class MyController extends GetxController {
  StreamSubscription? _subscription;
  Timer? _timer;

  @override
  void onInit() {
    super.onInit();
    _subscription = stream.listen(...);
    _timer = Timer.periodic(...);
  }

  @override
  void onClose() {
    _subscription?.cancel();
    _timer?.cancel();
    super.onClose();
  }
}

9. Workers (ever, once, debounce)

반응형 변수 변화에 자동으로 함수 실행.

class SearchController extends GetxController {
  var searchText = ''.obs;

  @override
  void onInit() {
    // 1초 debounce로 API 호출
    debounce(searchText, (_) => searchAPI(),
      time: Duration(seconds: 1));

    // 값이 변경될 때마다 실행
    ever(searchText, (_) => print('Changed'));

    // 처음 한 번만 실행
    once(searchText, (_) => print('First change'));

    super.onInit();
  }
}

10. GetxService로 영구 컨트롤러

앱 전체에서 유지되는 서비스. Get.delete로도 제거 불가.

class SettingsService extends GetxService {
  var isDarkMode = false.obs;

  Future<SettingsService> init() async {
    // 초기화 로직
    return this;
  }
}

// main.dart
await Get.putAsync(() => SettingsService().init());

// 어디서든 접근
final settings = Get.find<SettingsService>();

11. Bindings로 의존성 관리

페이지별 의존성을 라우트에 바인딩. 자동 정리.

class HomeBinding extends Bindings {
  @override
  void dependencies() {
    Get.lazyPut(() => HomeController());
    Get.lazyPut(() => ApiService());
  }
}

// 라우트 정의
GetPage(
  name: '/home',
  page: () => HomePage(),
  binding: HomeBinding(),
)

12. Middleware로 라우트 가드

인증, 권한 체크 등 라우트 접근 제어.

class AuthMiddleware extends GetMiddleware {
  @override
  RouteSettings? redirect(String? route) {
    final authService = Get.find<AuthService>();
    return authService.isLoggedIn
      ? null
      : RouteSettings(name: '/login');
  }
}

// 라우트에 적용
GetPage(
  name: '/profile',
  page: () => ProfilePage(),
  middlewares: [AuthMiddleware()],
)

13. 국제화 (i18n)

다국어 지원. 키-값 기반 번역 시스템.

class Messages extends Translations {
  @override
  Map<String, Map<String, String>> get keys => {
    'en_US': {
      'hello': 'Hello',
      'welcome': 'Welcome'
    },
    'ko_KR': {
      'hello': '안녕하세요',
      'welcome': '환영합니다'
    },
  };
}

// main.dart
GetMaterialApp(
  translations: Messages(),
  locale: Locale('ko', 'KR'),
)

// 사용
Text('hello'.tr) // "안녕하세요"

14. 테마 관리

다크모드 전환. 상태 유지 및 즉시 적용.

class ThemeController extends GetxController {
  var isDark = false.obs;

  void toggleTheme() {
    isDark.value = !isDark.value;
    Get.changeTheme(
      isDark.value ? ThemeData.dark() : ThemeData.light()
    );
  }
}

// 사용
Obx(() => Switch(
  value: controller.isDark.value,
  onChanged: (_) => controller.toggleTheme(),
))

15. 실전 예제: TODO 앱

상태관리, CRUD, 리스트 렌더링 통합 예제.

class TodoController extends GetxController {
  var todos = <Todo>[].obs;

  void addTodo(String title) {
    todos.add(Todo(title: title));
  }

  void removeTodo(int index) {
    todos.removeAt(index);
  }

  void toggleDone(int index) {
    todos[index].isDone = !todos[index].isDone;
    todos.refresh(); // 리스트 갱신
  }
}

// UI
Obx(() => ListView.builder(
  itemCount: controller.todos.length,
  itemBuilder: (context, index) =>
    CheckboxListTile(
      value: controller.todos[index].isDone,
      onChanged: (_) => controller.toggleDone(index),
    ),
))

16. 실전 예제: 폼 검증

실시간 폼 검증 및 에러 메시지 표시.

class FormController extends GetxController {
  var email = ''.obs;
  var password = ''.obs;

  String? get emailError =>
    email.value.isEmpty ? 'Email required' :
    !email.value.contains('@') ? 'Invalid email' : null;

  String? get passwordError =>
    password.value.length < 6 ? 'Min 6 characters' : null;

  bool get isValid =>
    emailError == null && passwordError == null;
}

// UI
Obx(() => TextField(
  onChanged: (v) => controller.email.value = v,
  decoration: InputDecoration(
    errorText: controller.emailError,
  ),
))

17. 주의사항

GetX 사용 시 메모리 누수와 성능 문제 방지 가이드.

// ✅ onClose()에서 리소스 정리
@override
void onClose() {
  _subscription?.cancel();
  super.onClose();
}

// ✅ 지연 로딩으로 메모리 절약
Get.lazyPut(() => Controller());

// ✅ Bindings로 자동 정리
GetPage(binding: HomeBinding())

// ✅ Workers는 onInit()에서 등록
debounce(variable, callback);

// ❌ onClose() 없이 Stream/Timer 방치 금지
// ❌ Get.put() 남용 금지 (필요할 때만)
// ❌ Obx 안에서 복잡한 로직 금지
// ❌ 전역 상태 과다 사용 금지

패키지 정보

pub.dev: https://pub.dev/packages/get

version: 4.7.2

likes: 15.4k

Publisher: getx.site