Flutter/Package

[Flutter] GetX ⑦ - Utils (GetConnect, StateMixin)

찌김이 2022. 9. 5. 06:00
728x90
반응형
 

get | Flutter Package

Open screens/snackbars/dialogs without context, manage states and inject dependencies easily with GetX.

pub.dev

 

설정

pubspec.yaml

dependencies:
  get: ^4.6.5

 

main.dart

  • MaterialApp 을 GetMaterialApp 으로 변경해주세요.
import 'package:flutter/material.dart';
import 'package:get/get.dart';

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

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

  @override
  Widget build(BuildContext context) {
  	
    // MaterialApp 을 GetMaterialApp 으로 변경
    return GetMaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const SampleScreen(),
    );
  }
}

 

 

 

GetConnect

http 통신을 할 때 사용되는 GetConnect 입니다.

 

사용 방법

  • class 를 만들고 GetConnect 를 상속받으면 됩니다.
  • get, post, put, delete 등 쉽게 구현할 수 있습니다.
class UserProvider extends GetConnect {
  // Get request
  Future<Response> getUser(int id) => get('http://youapi/users/$id');
  // Post request
  Future<Response> postUser(Map data) => post('http://youapi/users', body: data);
  // Post request with File
  Future<Response<CasesModel>> postCases(List<int> image) {
    final form = FormData({
      'file': MultipartFile(image, filename: 'avatar.png'),
      'otherFile': MultipartFile(image, filename: 'cover.png'),
    });
    return post('http://youapi/users/upload', form);
  }

  GetSocket userMessages() {
    return socket('https://yourapi/users/socket');
  }
}

 

  • init 에서 baseUrl contentType 등 여러가지 값들을 셋팅할 수 있습니다.
import 'package:get/get.dart';

class SampleProvider extends GetConnect {
  @override
  void onInit() {
    super.onInit();
    
    httpClient
      ..baseUrl = 'your baseUrl'

      ..defaultContentType = 'application/json'

      ..timeout = const Duration(seconds: 10)
      
      ..addRequestModifier<dynamic>((request) {
        request.headers['Authorization'] = 'token value';
        return request;
      });
  }
  
  .
  .
  .
}

 

 

 

StateMixin

  • controller class 에 믹스인 해주어 상태에 따라 UI 를 관리 합니다.
RxStatus.loading();
RxStatus.success();
RxStatus.empty();
RxStatus.error('message');

 

  • controller 에서 change 를 이용하여 상태를 변경해줍니다.
change(data, status: RxStatus.success());

 

 

사용 예시

sample_controller.dart

  • 예시로 버튼을 누를 때 마다 getSample 호출하여 상태가 바뀌는 것을 구현합니다.
  • controller class 에서 StateMixin<T> 을 믹스인 해주세요.
  • getSample 에서는 Random 과 swich 를 이용하여 상태를 무작위로 바꿔줍니다.
class SampleController extends GetxController with StateMixin {

  final RxString _sample = '성공했어요.'.obs;
  RxString get sample => _sample;
  
  @override
  void onInit() {
    getSample();
    super.onInit();
  }

  void getSample() async {
    change(null, status: RxStatus.loading());

    await Future.delayed(const Duration(seconds: 1));

    final randomNum = Random();
    switch (randomNum.nextInt(3)) {
      case 0 :
        change(null, status: RxStatus.empty());
        break;
      case 1 :
        change(null, status: RxStatus.error('예외 발생 !'));
        break;
      case 2 :
        change(null, status: RxStatus.success());
        break;
    }
  }
}

 

sample_screen.dart

  • controller.obx 를 통해서 상황에 따라 ui 를 그려줍니다.
  • onLoading 에서는 null 을 넣어주면 CircularProgressIndicator 로 나타납니다.
class SampleScreen extends StatelessWidget {
  final controller = Get.find<SampleController>();

  Widget _sampleText(String text, Color color) {
    return Text(
      text,
      style: TextStyle(color: color, fontSize: 30),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            controller.obx(
              (state) => _sampleText('${controller.sample}', Colors.blue),
              onError: (error) => _sampleText('에러 났어요. - $error', Colors.red),
              onEmpty: _sampleText('비어 있어요', Colors.green),
              onLoading: null,
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                controller.getSample();
              },
              child: Text('확인'),
            )
          ],
        ),
      ),
    );
  }
}

 

 

 

 

728x90
반응형