[Flutter] 스나이퍼팩토리 Flutter 중급과정 (9)

GONG·2023년 5월 5일
0
post-thumbnail

30일차 과제 링크 👉 30일차 과제

Rx

  • 관측 가능한 데이터타입
  • 값이 바뀔 때마다 변경을 감지하고 화면을 업데이트

obs

  • Rx 데이터 타입을 사용하여 상태 관리를 할 때 상태 변경을 감지하는데 사용되는 메서드
  • 해당 변수를 Rx 데이터 타입으로 변환하고 해당 변수를 감지할 수 있게 됨
  • 이후 해당 변수의 값이 변경될 때마다 이를 감지하여 상태 업데이트를 처리할 수 있음

변수 선언

  • var myLevel = 1.obs;
  • var myLevel = RxInt(1);
  • RxInt myLevel = 1.obs; → 추천

기존 데이터타입

  • int : RxInt
  • String : RxString
  • List : RxList
  • Map : RxMap
  • bool : RxBool
  • Rx

커스텀클래스

  • Rx<class명>

nullable

  • Rxn

  • 새로운 값을 넣어줄 때는 함수처럼 활용
    RxInt myAge = 99.obs;
    myAge = 3.obs;
    myAge(e);

Observable operator

.value

  • 가장 기본적인 Observable 타입
  • 단순히 값을 저장
  • 화면의 텍스트 또는 이미지를 업데이트하는 등의 간단한 작업을 수행할 수 있음
    final count = 0.obs;
    // .obs를 사용하여 Observable 객체로 변경
    
    Text('Count: ${count.value}'),
    // .value를 사용하여 Observable의 현재 값을 가져오기
    • List는 제외
      RxList<String> myFriends = ['a', 'b', 'c'].obs;
      
      ...
      var controller = Get.find();
      Text(controller.myFriends.length.toString());       // O
      Text(controller.myFriends.value.length.toString()); // X

.rx

  • .value와 유사하지만 다른 operator를 적용할 수 있는 "Wrapper Observable"을 만듦
    final name = 'John'.obs.rx;
    // .rx를 사용하여 Wrapper Observable 객체 만들기
    
    Text('${name.value}'),
    // .value를 사용하여 현재 값을 가져오기

.obs

  • Observable 객체로 변환
  • 객체의 변경을 감지하고, 이에 따라 화면을 업데이트할 수 있음
    final list = [1, 2, 3].obs;
    // .obs를 사용하여 List를 Observable 객체로 변경
    
    Obx(() => Text(list.value.toString())),
    // Obx를 사용하여 변경 사항을 감지하고 화면을 업데이트

.isNull

  • 값이 null인지 여부를 확인
    final name = ''.obs;
    // .obs를 사용하여 Observable 객체 만들기
    
    Text('${name.value.isNull ? "Unknown" : name.value}'),
    // .isNull을 사용하여 name.value가 null인 경우 "Unknown"을, 그렇지 않은 경우 name.value를 표시

.default

  • 값이 null인 경우 기본값을 설정
    final name = ''.obs;
    // .obs를 사용하여 Observable 객체 만들기
    
    Text('${name.value.default("Unknown")}'),
    // .default를 사용하여 name.value가 null인 경우 "Unknown"을, 그렇지 않은 경우 name.value를 표시

.where

  • List나 Map 등의 Collection 객체에서 특정 조건을 만족하는 항목만 필터링
    final list = [1, 2, 3].obs;
    // .obs를 사용하여 List를 Observable 객체로 변경
    
    final filteredList = list.where((item) => item > 1).obs;
    // .where를 사용하여 List에서 값이 1보다 큰 항목만을 필터링
    
    Obx(() => Text(filteredList.value.toString())),
    // Obx를 사용하여 변경 사항을 감지하고 화면을 업데이트

Obx

  • Rx 데이터 타입을 사용할 때 UI를 업데이트하는 데 사용되는 위젯
  • Rx 데이터 타입을 구독하여 값의 변경을 감지하고, 해당 값이 변경될 때마다 Obx 위젯 내의 빌더 함수를 호출하여 UI를 업데이트

Rx, Obx 사용해보기

  • main.dart
    import 'controller/global_data_controller.dart';
    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    import 'page/main_page.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      
      Widget build(BuildContext context) {
        Get.put(GlobalDataController());
    
        return MaterialApp(
          home: MainPage(),
        );
      }
    }

controller

  • global_data_controller.dart
    import 'package:get/get.dart';
    
    class GlobalDataController extends GetxController {
      RxInt myLevel = 1.obs;
    }

page

  • main_page.dart
    import '../controller/global_data_controller.dart';
    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    class MainPage extends StatelessWidget {
      const MainPage({Key? key}) : super(key: key);
    
      
      Widget build(BuildContext context) {
        var controller = Get.find<GlobalDataController>();
    
        return Scaffold(
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Obx(() => Text(controller.myLevel.value.toString())),
                ElevatedButton(
                  onPressed: () {
                    controller.myLevel(controller.myLevel.value += 1);
                  },
                  child: Text('+1'),
                )
              ],
            ),
          ),
        );
      }
    }

Rx - Worker

  • 데이터 변경을 감지하고, 이에 대한 작업을 수행

ever

  • Observable 객체가 변경될 때마다 항상 실행되는 함수를 정의
    final count = 0.obs;
    // .obs를 사용하여 Observable 객체 만들기
    
    count.ever((value) => print('Count is now: $value'));
    // .ever를 사용하여 count의 값이 변경될 때마다 실행되는 함수를 정의

once

  • Observable 객체가 최초로 변경될 때 한 번만 실행되는 함수를 정의
    final name = ''.obs;
    // .obs를 사용하여 Observable 객체 만들기
    
    name.once((value) => print('Hello, $value!'));
    // .once를 사용하여 name의 값이 최초로 변경될 때 실행되는 함수를 정의

debounce

  • Observable 객체가 변경된 후 지정된 시간이 경과할 때까지 다른 변경 사항을 무시할 수 있음
    final searchText = ''.obs;
    // .obs를 사용하여 Observable 객체 만들기
    
    searchText.debounce(Duration(milliseconds: 500)).listen((value) => print('Search for: $value'));
    // .debounce를 사용하여 searchText가 변경되고 500밀리초가 지난 후에 실행되는 함수를 정의
    // 사용자가 검색어를 입력하다가 잠시 멈추면 검색을 시작

interval

  • Observable 객체가 일정한 시간 간격으로 반복되는 값을 생성
    final counter = 0.obs;
    // .obs를 사용하여 Observable 객체 만들기
    
    counter.interval(Duration(seconds: 1)).listen((value) => print('Count is now: $value'));
    // .interval을 사용하여 1초마다 counter의 값을 출력하는 함수를 정의
    // 일정한 간격으로 반복되는 작업을 수행할 수 있음

onInit()

  • 해당 클래스가 최초로 생성될 때 호출되는 메서드
    import 'package:get/get.dart';
    
    class HomeController extends GetxController {
      var count = 0;
    
      
      void onInit() {
        super.onInit();
        // 데이터 초기화 등의 작업 수행
        count = 10;
      }
    }

연습

  • user 데이터가 null인 경우 login 페이지로 이동하고, 그렇지 않은 경우 main 페이지로 이동

  • main.dart

    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    import 'controller/global_data_controller.dart';
    import 'model/user.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      
      Widget build(BuildContext context) {
    
        var controller = Get.put(GlobalDataController());
    
        return GetMaterialApp(
          home: Scaffold(
            body: Center(
              child: TextButton(
                onPressed: (){
                  print(controller.user);
                  controller.user(User(id: 'asdf', nickname: 'asd'));
                },
                child: Text('로그인'),
              ),
            ),
          )
        );
      }
    }

controller

  • global_data_controller.dart
    import 'package:first_app/Flutter/GetX/ever/page/main_page.dart';
    import 'package:get/get.dart';
    
    import '../model/user.dart';
    import '../page/login_page.dart';
    
    class GlobalDataController extends GetxController {
      Rxn<User> user = Rxn();
    
      
      void onInit() {
        super.onInit();
        print('컨트롤러 생성');
    
        ever(user, (value) {
          if (value == null) {
            Get.to(() => LoginPage());
            return;
          }
          Get.to(() => MainPage());
          return;
        });
      }
    }

model

  • user.dart
    class User {
      String id;
      String nickname;
    
      User({required this.id, required this.nickname});
    }

page

  • main_page.dart
    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    import '../controller/global_data_controller.dart';
    
    class MainPage extends StatelessWidget {
      const MainPage({super.key});
    
      
      Widget build(BuildContext context) {
    
        var controller = Get.find<GlobalDataController>();
    
        return Scaffold(
          body: Center(
            child: Text('main_page'),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              controller.user.value = null;
            },
            child: Icon(Icons.logout),
          ),
        );
      }
    }
  • login_page.dart
    import 'package:flutter/material.dart';
    
    class LoginPage extends StatelessWidget {
      const LoginPage({super.key});
    
      
      Widget build(BuildContext context) {
    
        return Scaffold(
          body: Center(
            child: Text('login_page'),
          ),
        );
      }
    }


30일차 끝!

GetX 재밋다.............이게되네..............

profile
우와재밋다

1개의 댓글

comment-user-thumbnail
2023년 5월 6일

답글 달기