반응형

코딩을 공부하면서 때때로 한자를 공부하는 느낌이 든다. 

네이버 어학사전에서는 종속성을 아래와 같이 설명한다. IT용어인데 한자도 있다....소름

종속성
[ dependency음성듣기 , 從屬性 ]

관계 모델에서 다른 실체 또는 속성이 존재하는 경우에 한하여 어떤 실체 또는 속성의 존재 의의가 있음을 의미하는 실체 간 또는 속성 간의 관련 관계. 관계 모델에서는 데이터 구조를 형식화하는 경우에 하나의 관계 중에 포함되는 몇 가지 속성 간 사상(寫像)의 성질(종속 관계)이 중요하다. 종속 관계에는 함수 종속성, 결합 종속성, 다치 종속성, 추이 종속성 등이 있다.

[네이버 지식백과] 종속성 [dependency, 從屬性] (IT용어사전, 한국정보통신기술협회)

 

어렵다. 그래서 내 식대로 정리해본다. 

 

나는 음식점을 운영하고 있다. 콩나물 불고기, 찜닭을 판다. 

각 메뉴마다 같은 매콤과 간장 양념을 쓰고 있다. 고로 나의 메뉴는 매콤 콩불, 간장 콩불, 매콤 찜닭, 간장 찜닭 이렇게 4가지를 판매하는 것이다. 그렇다면 위 4가지 음식을 할 때를 코드로 변환하면 

 

클래스 매콤 콩불 

변수 돼지고기 

함수 매콤양념장을 넣고 끓인다. 



클래스 간장 콩불

변수 돼지고기

함수 간장양념장을 넣고 끓인다. 



클래스 매콤 찜닭

변수 닭고기 

함수 간장양념장을 넣고 끓인다. 



클래스  간장 찜닭

변수 닭고기 

함수 매콤양념장을 넣고 끓인다.

 

이렇게 코드를 짤 수 있겠다. 보면 반복적인 변수나 함수가 보인다.  이것을 인스턴스화 해서 클래스에 종속시켜 보면 아래와 같이 보다 더 간결한 코드를 만들 수 있게 된다. (솔직히 이게 맞는지 두렵다. 지나가는 개발자님 알려주세요 )

 

함수 매콤 = 매콤 양념을 넣고 볶는다
함수 간장 = 간장 양념을 넣고 볶는다
변수 돼지= 돼지고기
변수 닭= 닭고기 



클래스 메뉴 

 매콤 콩불

  변수 돼지

  함수 매콤


 간장 콩불

  변수 닭

  함수 간장


 매콤 찜닭

  변수 닭 

  함수 매콤



 간장 찜닭 

  변수 닭 

  함수 간장

 

 

 

기존의 플러터에서 제공하는 종속성 관리에 효과적인 Provider context, inheritedWidget 방법이 있다. 하지만 코드가 길다. 

Get x 는 짧다. 

 

Get.put

가장 일반적인 방법 

Get.put<SomeClass>(SomeClass());
Get.put<LoginController>(LoginController(), permanent: true);
Get.put<ListItemController>(ListItemController, tag: "some unique string");

 

Get.lazyPut

인스턴스하게 사용하는 경우에만 의존성을 lazyLoad 할 수 있습니다. 계산 비용이 많이 드는 클래스나 한곳에서 다양한 클래스를 당장 사용하지 않으면서 인스턴스화 하기를 원한다면(Bindings 클래스처럼) 매우 유용합니다.

/// ApiMock은 처음으로 Get.find<ApiMock>을 사용하는 경우에만 호출됩니다.
Get.lazyPut<ApiMock>(() => ApiMock());

Get.lazyPut<FirebaseAuth>(
  () {
    // 어떤 로직이 필요하다면 ...
    return FirebaseAuth();
  },
  tag: Math.random().toString(),
  fenix: true
)

Get.lazyPut<Controller>( () => Controller() )

 

Get.putAsync

만약 비동기로 인스턴스를 등록하길 원하면 Get.putAsync를 사용할 수 있습니다.:

Get.putAsync<SharedPreferences>(() async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setInt('counter', 12345);
  return prefs;
});

Get.putAsync<YourAsyncClass>( () async => await YourAsyncClass() )

 

Get.find

 

final controller = Get.find<Controller>();
// OR
Controller controller = Get.find();

// 그렇습니다. 마법 같아요. Get은 controller를 찾고 배달해 줍니다.
// Get은 백만개의 contrller를 인스턴스화해서 가질수 있고 항상 올바르게 전달해 줍니다.

 

 

후아 어렵다. 

바인딩이라는 개념도 있지만 그건 천천히 공부해야겠다. 

일단은 여기까지

반응형

'Flutter-플러터 > 플러터 공부' 카테고리의 다른 글

final const  (0) 2022.10.25
Get X 4편 - 테마 변경  (0) 2022.10.14
Get x 2편 - Get x의 상태관리에 대해  (1) 2022.10.11
Get X 1편 - Get X에 대해  (0) 2022.10.09
MVC, MVVM 패턴이란?  (2) 2022.10.06
반응형

 

 

getx/state_management.md at master · jonataslaw/getx (github.com)

 

GitHub - jonataslaw/getx: Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies eas

Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get. - GitHub - jonataslaw/getx: Open screens/snackbars/dialogs/bottomSheets without c...

github.com

 

 

위 링크는 Get x를 만든 개발자가 Get x 대한 설명서이다. 항상 느끼는 것이지만 개발자들의 설명은 뭔가 장황하다. (다 그런것은 아니지만..)하나하나 읽다보면 했던 이야기가 또 나온다. 자신이 만든 패키지에 대한 사랑이 이성을 놓게 만드는 것 같다. 

 

그래도 위 Get x가 Flutter 로 어플을 개발하는데에 있어서 엄청난 혁신을 가져온 것은 맞다. 

그런면에 있어서 정말 감사하게 생각한다. 

 

Get X로 상태관리를 하게 된다면 가장 큰 장점은 Ram의 소모가 적다는 것이다. 기존 패키지로 어플을 구성하게 되면 상태 변환이 필요한 어플들은 Stateful 위젯을 사용해야 하고 changeNotifier 클래스를 사용해야 한다. 위젯이 중첩된다면 모든 클래스의 위젯들이 업데이트가 필요하게된다. 그러한 상황이 곧 Ram의 낭비라고 Get X의 개발자는 이야기한다. 그래서  Get x를 이용하게 되면 더 정확하게는 Obx(())의 기능을 사용하게 되면 Listview안의 Checkbox가 있고 두 위젯을 각각의 Obx(())가 보고 있다면 각각위 위젯이 변경 될때만 상태가 업데이트가 된다. 

 

또한 기존의 '진탁'이라는 Text 변수가 다시 한번 '진탁'이라고 변경될 때도 이미 Obx(())가 '진탁'으로 인식을 하고 있기에 재구성을 하지 않는다. (위젯이 복잡하지 않을 때는 큰 차이가 없지만 위젯이 복잡하고 , 데이터의 양이 많아진다면 엄청난 차이라고 생각한다.)

 

반응형 변수를 만드는 방법은 총 3가지를 소개하고 있다. 하지만 변수를 선언후 .obs; 를 입력하는 것으로 실사용자들은 많이사용하고 있다. 고로 이 한가지만 알고 있으면 문제 없다. 

 

fianl name = ''.obs;

final count = 0.obs;

 

결론적으로 Get x를 만든 개발자가 추구하는 것은 '최소의 종속성으로 라우트,상태,종속성 관리를 하는것' 이라고 이야기하고 있다. 

 

직관적, 효율 이 두가지에 미치면 이런 좋은 패키지를 개발 할 수 있는 것 같다. 부럽다. 이 개발자의 광기와 능력이..

 

 

 

 

 

반응형

'Flutter-플러터 > 플러터 공부' 카테고리의 다른 글

Get X 4편 - 테마 변경  (0) 2022.10.14
Get x 3편 - 종속성 관리  (0) 2022.10.14
Get X 1편 - Get X에 대해  (0) 2022.10.09
MVC, MVVM 패턴이란?  (2) 2022.10.06
플러터 Stateful 위젯의 생명주기 ??  (0) 2022.09.21
반응형
getx/README.ko-kr.md at master · jonataslaw/getx (github.com)
 

GitHub - jonataslaw/getx: Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies eas

Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get. - GitHub - jonataslaw/getx: Open screens/snackbars/dialogs/bottomSheets without c...

github.com

 

코딩의 발전의 속도는 무자비하다 하지만 그 발전의 방향은 일관성이 존재한다. 바로 "효율" 이다. 

 

1. 공간의 효율 -> 프로그램의 실행횟수를 줄여서 메모리를 적게 쓰게 하자 

2. 시간의 효율-> 프로그램의 실행횟수를 최소화해서 빠른시간내에 처리가 가능하게 하자 

3. 피드백의 효율 -> 코드 읽는 시간을 줄여서 빠르게 문제점을 해결하자 

 

 

그 "효율" 때문에 최근 많은 사람들로부터 선택받는 개발언어가 있다. 바로 Dart! Dart는 Flutter 프레임워크를 사용해서 하나의 코드로 안드로이드, IOS, 웹, 윈도우까지 프로그램을 만들 수 있는 매우"효율" 적인 언어이다. 회사 입장에서는 개발자를 안드로이드 1명, IOS 1명씩 둘 필요가 없어지니 말이다. 

 

Flutter 가 한 때는 가장 인기 없는 언어로 선정된적도 있지만 지금은  더 "효율"적인 모습들로 개선이 되고 있다. 

그렇기에 많은 사람들로부터 선택을 받고 있는 듯 하다. 

 

 오늘의 주인공은 Flutter 의 "효율" 적인 발전의 한 모습인  Get X이다.  지금 부터 나오는 내용은 위에 링크를 참고해서 만들었다.

 

Get X는 "Flutter made easy" 라는 목표를 두고 있다. 

 

 

기존에 플러터 새로운 프로젝트를 열면 실행되었던 카운트앱이 있다. 

 

 

아래는 그 카운트앱을 Get X로 개선한 모습이다. 기존에 100줄의코드양이 30줄로 줄어들었다. 

Get X는 불필요한 context를 줄이고 좀 더 직관적으로 코드를 제공한다. 

get. , .obs , obx() 등등 

 

void main() => runApp(GetMaterialApp(home: Home()));

 

class Controller extends GetxController{
  var count = 0.obs;
  increment() => count++;
}

 

class Home extends StatelessWidget {

  @override
  Widget build(context) {

    // Get.put()을 사용하여 클래스를 인스턴스화하여 모든 "child'에서 사용가능하게 합니다.
    final Controller c = Get.put(Controller());
    
    return Scaffold(
      // count가 변경 될 때마다 Obx(()=> 를 사용하여 Text()에 업데이트합니다.
      appBar: AppBar(title: Obx(() => Text("Clicks: ${c.count}"))),

      // 8줄의 Navigator.push를 간단한 Get.to()로 변경합니다. context는 필요없습니다.
      body: Center(child: ElevatedButton(
              child: Text("Go to Other"), onPressed: () => Get.to(Other()))),
      floatingActionButton:
          FloatingActionButton(child: Icon(Icons.add), onPressed: c.increment));
  }
}

class Other extends StatelessWidget {
  // 다른 페이지에서 사용되는 컨트롤러를 Get으로 찾아서 redirect 할 수 있습니다.
  final Controller c = Get.find();

  @override
  Widget build(context){
     // 업데이트된 count 변수에 연결
     return Scaffold(body: Center(child: Text("${c.count}")));
  }
}

 

 

 

이렇듯 좀더 짧은 구문, 효과적인 기능성으로 기존에  Bloc, Provider 로 만들었던 코드를 Get X로 변환하는 개발자가 늘고 있다. 

 

 

 

반응형
반응형

Get x를 만들기 위해서 코드 구조는 

lip 파일 안에 mvc 순으로 만들기 

model : 내용물

view :  화면에 표시되는 내용

control : 이벤트 발생 후  상태 업데이트 

 

아래 코드는 

model - widget

view - screen

control - control  

폴더로 만들어서 사용했음 

 

출처 

Flutter-GetX-calculator/lib at master · shistastic/Flutter-GetX-calculator (github.com)

 

GitHub - shistastic/Flutter-GetX-calculator: Tests with GetX

Tests with GetX. Contribute to shistastic/Flutter-GetX-calculator development by creating an account on GitHub.

github.com


(57) Flutter - GetX Calculator - YouTube

 

 

코드 리뷰 

 

1. 파일 읽기 

- 아래 코드는 아래 3가지로 구성되어 있음 

Widget(model)  - 전체적인 뼈대를 제작하는 곳 

입력 숫자칸 1 , 중간에 연산자 기호 , 입력숫자칸 2, 연산칸과 결과값을 구분짓는 라인 ,

screen(view). - 숫자칸 만들기 ->  화면에 표시된 버튼을 구성하고 그 버튼에 Widget, control 에 담겨져 있는 함수를 호출한다. 

control  - 결과값에 관한 함수 다양한 연산자로 결과값을 변하게 한다. 

폴더로 만들어서 사용했음 

 

2. 함수 읽기 

  - 메인 다트에서는 Get x를 사용하기에 Stateful  위젯이 아닌 Stateless 위젯을 사용 

  •  screen.dart
  • 에서 MathResults(),으로 결과값을 보여주게 만듬
  • 각 버튼에 "+" or "연산기호" 을 만들고 calculatorController.selectOperation("X"), 로 컨트롤러에 있는 함수로 지정 , 숫자는 "8" 문자열로 보이게함 

 

  • control
  • class CalculatorController extends GetxController {
      var firstNumber = "10".obs;
      var secondNumber = "20".obs;
      var mathResult = "30".obs;
      var operation = "+".obs;  //뒤에 .obs를 붙여서 실시간 데이터 를 관찰하게 만듬 = Stateful 위젯 기능 
  • switch (operation.value) {
          case "+":
            mathResult.value = "${num1 + num2}";
            break;
          case "-":
            mathResult.value = "${num1 - num2}";
            break;
          case "/":
            mathResult.value = "${num1 / num2}";
            break;
          case "X":
            mathResult.value = "${num1 * num2}";
            break;
          default:
            return;
        }

3. 위젯 읽기 

 

버튼을 만들고 텍스트로 숫자 표시 -> 이벤트 발생 함수 -> 정해진 숫자가 입력되게 하는 방식 

연산자기호도 동일 + 입력하면 + 아래 함수가 호출됨 

switch는 다중 조건문 , 여러 조건이 필요할 때 가독성이 좋음 

 

switch (operation.value) {
      case "+":
        mathResult.value = "${num1 + num2}";
        break;
      case "-":
        mathResult.value = "${num1 - num2}";
        break;
      case "/":
        mathResult.value = "${num1 / num2}";
        break;
      case "X":
        mathResult.value = "${num1 * num2}";
        break;
      default:
        return;
    }

 

 


 

main.dart

 

import 'package:calculadora/screens/calculator_screen.dart';
import 'package:flutter/material.dart';

 
void main() => runApp(MyApp());
 
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Material App',
      home: CalculatorScreen(),
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: Colors.black
      ),
    );
  }
}

 


screen.dart : 화면에 나오는 버튼 위치 + 이벤트 지정

 

import 'package:calculadora/controllers/calculator_controller.dart';
import 'package:calculadora/widgets/calc_button.dart';
import 'package:calculadora/widgets/math_results.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class CalculatorScreen extends StatelessWidget {
  final calculatorController = Get.put(CalculatorController());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: SafeArea(
      child: Container(
        margin: EdgeInsets.symmetric(horizontal: 10),
        child: Column(
          children: [
            Expanded(
              child: Container(),
            ),
            MathResults(),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                CalculatorButton(
                  text: 'AC',
                  bgColor: Color(0xffA5A5A5),
                  onPressed: () => calculatorController.resetAll(),
                ),
                CalculatorButton(
                  text: '+/-',
                  bgColor: Color(0xffA5A5A5),
                  onPressed: () =>
                      calculatorController.changeNegativePositive(),
                ),
                CalculatorButton(
                  text: 'del',
                  bgColor: Color(0xffA5A5A5),
                  onPressed: () => calculatorController.deleteLastEntry(),
                ),
                CalculatorButton(
                  text: '/',
                  bgColor: Color(0xffF0A23B),
                  onPressed: () => calculatorController.selectOperation("/"),
                ),
              ],
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                CalculatorButton(
                  text: '7',
                  onPressed: () => calculatorController.addNumber("7"),
                ),
                CalculatorButton(
                  text: '8',
                  onPressed: () => calculatorController.addNumber("8"),
                ),
                CalculatorButton(
                  text: '9',
                  onPressed: () => calculatorController.addNumber("9"),
                ),
                CalculatorButton(
                  text: 'X',
                  bgColor: Color(0xffF0A23B),
                  onPressed: () => calculatorController.selectOperation("X"),
                ),
              ],
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                CalculatorButton(
                  text: '4',
                  onPressed: () => calculatorController.addNumber("4"),
                ),
                CalculatorButton(
                  text: '5',
                  onPressed: () => calculatorController.addNumber("5"),
                ),
                CalculatorButton(
                  text: '6',
                  onPressed: () => calculatorController.addNumber("6"),
                ),
                CalculatorButton(
                  text: '-',
                  bgColor: Color(0xffF0A23B),
                  onPressed: () => calculatorController.selectOperation("-"),
                ),
              ],
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                CalculatorButton(
                  text: '1',
                  onPressed: () => calculatorController.addNumber("1"),
                ),
                CalculatorButton(
                  text: '2',
                  onPressed: () => calculatorController.addNumber("2"),
                ),
                CalculatorButton(
                  text: '3',
                  onPressed: () => calculatorController.addNumber("3"),
                ),
                CalculatorButton(
                  text: '+',
                  bgColor: Color(0xffF0A23B),
                  onPressed: () => calculatorController.selectOperation("+"),
                ),
              ],
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                CalculatorButton(
                  text: '0',
                  big: true,
                  onPressed: () => calculatorController.addNumber("0"),
                ),
                CalculatorButton(
                  text: '.',
                  onPressed: () => calculatorController.addDecimalPoint(),
                ),
                CalculatorButton(
                  text: '=',
                  bgColor: Color(0xffF0A23B),
                  onPressed: () => calculatorController.calculateResult(),
                ),
              ],
            ),
          ],
        ),
      ),
    ));
  }
}

 


cal_button.dart. :  버튼의 스타일을 지정해주기 

 

import 'package:flutter/material.dart';

class CalculatorButton extends StatelessWidget {

  final Color bgColor;
  final bool big;
  final String text;

  final Function onPressed;

  CalculatorButton({
    Key? key, 
    bgColor,
    this.big = false, 
    required this.text, 
    required this.onPressed,
  }): this.bgColor = bgColor ?? Color(0xff333333),
      super(key: key);
      

  @override
  Widget build(BuildContext context) {
    // Button
    final buttonStyle = TextButton.styleFrom(
        backgroundColor: this.bgColor,
        primary: Colors.white,
        shape: StadiumBorder(),
    );

    return Container(
      margin: EdgeInsets.only( bottom: 10, right: 5, left: 5 ),
      child: TextButton(
        style: buttonStyle,
        child: Container(
          width: this.big ? 150 : 65,
          height: 65,
          child: Center(
            child: Text( this.text , style: TextStyle( fontSize: 30, fontWeight: FontWeight.w300 ),)
          ),
        ),
        onPressed: () => this.onPressed(),
      ),
    );
  }
}

 


line_separator.dart

 

import 'package:flutter/material.dart';

class LineSeparator extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: 2,
      color: Colors.white.withOpacity(0.4),
      margin: EdgeInsets.symmetric( vertical: 10 )
    );
  }
}

 


main_result.dart

import 'package:flutter/material.dart';

class MainResultText extends StatelessWidget {
  final String text;

  const MainResultText({Key? key, required this.text}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.only(bottom: 20),
      width: double.infinity,
      alignment: Alignment.centerRight,
      child: FittedBox(
          fit: BoxFit.contain,
          child: Text(this.text, style: TextStyle(fontSize: 50))),
    );
  }
}

 


math_results.dart

 

import 'package:calculadora/controllers/calculator_controller.dart';
import 'package:calculadora/widgets/line_separator.dart';
import 'package:calculadora/widgets/main_result.dart';
import 'package:calculadora/widgets/sub_result.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class MathResults extends StatelessWidget {
  final calculatorController = Get.find<CalculatorController>();

  @override
  Widget build(BuildContext context) {
    return Obx(
      () => Column(
        children: [
          SubResult(text: calculatorController.firstNumber.value),
          SubResult(text: calculatorController.operation.value),
          SubResult(text: calculatorController.secondNumber.value),
          LineSeparator(),
          MainResultText(text: calculatorController.mathResult.value),
        ],
      ),
    );
  }
}

 


sub_result.dart

 

import 'package:flutter/material.dart';

class SubResult extends StatelessWidget {

  final String text;

  const SubResult({Key? key, required this.text}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      alignment: Alignment.centerRight,
      child: Text( this.text , style: TextStyle(fontSize: 30 ) ),
    );
  }
}

 


calculator_controller.dart

 

import 'package:get/get.dart';

class CalculatorController extends GetxController {
  var firstNumber = "10".obs;
  var secondNumber = "20".obs;
  var mathResult = "30".obs;
  var operation = "+".obs;

  void resetAll() {
    firstNumber.value = "0";
    secondNumber.value = "0";
    mathResult.value = "0";
    operation.value = "+";
  }

  changeNegativePositive() {
    if (mathResult.startsWith("-")) {
      mathResult.value = mathResult.value.replaceFirst("-", "");
    } else {
      mathResult.value = "-" + mathResult.value;
    }
  }

  addNumber(String number) {
    if (mathResult.value == "0") {
      return mathResult.value = number;
    }

    if (mathResult.value == "-0") {
      return mathResult.value = "-" + number;
    }

    mathResult.value = mathResult.value + number;
  }

  addDecimalPoint() {
    if (mathResult.contains(".")) return;
    if (mathResult.startsWith("0")) {
      mathResult.value = "0.";
    } else {
      mathResult.value = mathResult.value + ".";
    }
  }

  selectOperation(String newOperation) {
    operation.value = newOperation;
    firstNumber.value = mathResult.value;
    mathResult.value = "0";
  }

  deleteLastEntry() {
    if (mathResult.value.replaceAll("-", "").length > 1) {
      mathResult.value =
          mathResult.value.substring(0, mathResult.value.length - 1);
    } else {
      mathResult.value = "0";
    }
  }

  calculateResult() {
    double num1 = double.parse(firstNumber.value);
    double num2 = double.parse(mathResult.value);

    secondNumber.value = mathResult.value;

    switch (operation.value) {
      case "+":
        mathResult.value = "${num1 + num2}";
        break;
      case "-":
        mathResult.value = "${num1 - num2}";
        break;
      case "/":
        mathResult.value = "${num1 / num2}";
        break;
      case "X":
        mathResult.value = "${num1 * num2}";
        break;
      default:
        return;
    }

    if (mathResult.value.endsWith(".0")) {
      mathResult.value =
          mathResult.value.substring(0, mathResult.value.length - 2);
    }
  }
}

반응형
반응형

자동차 생산의 역사는 포드가 만든 대량 생산체제 전 후로 나누고 있다. 그만큼 포드는 자동차 보급에 엄청난 혁신을 가지고 왔다. 

그 혁신은 코딩을 하는 개발자 세계에도 존재한다. 평범한 계산기 프로그램에도 필요한 코드의 양은 어마무시하다. 그렇기에  모든 코드를 main.dart에 쭉 쓰는 건 비효율적이다. 계산기에 필요한 구성품을 나누어 따로 보관하는 것이 MVC, MVVM 이다. 

 

MVC

-Model 

-View 

-Control 

 

MVVM 

-Model 

-View 

-ViewModel 

 

의 약자이다. 

 

두 가지를 알아본 결과 나같은 코딩을 이제 막 배우는 입장에서는 다 똑같다. 

앞으로 어플을 개발함에 있어 

 

lib 파일에 

Model 

View

Control 파일을 만드는 연습을 하려고 한다. 

그래야 내 부족한 코드를 봐주는 선배님들의 시간이 절약될테니 말이다. 

반응형
반응형

출처 -[플러터] Todo-App 만들기 (velog.io)

 

[플러터] Todo-App 만들기

🌈 간단한 Todo-list 만들기 ☀️ 1. 프로젝트 생성하기 프로젝트 생성 후, home에 todoApp()을 호출한다. todoApp은 상태값이 변하므로, Stateful 위젯을 사용한다. StatefulWidget을 상속받는 todoApp 클래스를

velog.io

 

 

1. 함수 읽기 

todo어플도 상태값이 변하니까 Sateful 위젯을 사용 

todoApp stateful 상속 위젯 생성 

"+ "아이콘을 앱바에 생성 -> 클릭 하면 다이얼로그 showDialog(); -> return값 AlertDialog 2칸의 텍스트필드 -> (hint)1. 글 제목, 2. 글 내용  입력 

 

저장하기 

Todo class 생성 

위와 같이 클래스를 만들어 주자 final을 통해 title, description 을 선언하고, Todo클래스의 생성자를 생선한다. 

Todo 클래스를 만드는 이유는 TextField에서 입력받은 값들을 저장하기 위해 만든 것

 

 

 

 

2. 디자인 읽기 

 

전체적인 리스트 뷰 

Inkwell 클릭이벤트 만들어주기 

 

 

 

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const todoApp(),
    );
  }
}

class Todo {
  final String title;
  final String description;

  Todo({required this.title, required this.description});
}

class todoApp extends StatefulWidget {
  const todoApp({Key? key}) : super(key: key);

  @override
  State<todoApp> createState() => _todoApp();
}

class _todoApp extends State<todoApp> {
  String title = "";
  String description = "";

  List<Todo> todos = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: Image.asset("assets/avartar.jpeg", fit: BoxFit.fill),
        title: Text("todo - list"),
        actions: [
          IconButton(
              onPressed: () {
                showDialog(
                  context: context,
                  builder: (_) {
                    return AlertDialog(
                      title: const Text('나의 할일'),
                      actions: [
                        TextField(
                          onChanged: (value) {
                            setState(() {
                              title = value;
                            });
                          },
                          decoration: InputDecoration(hintText: "글 제목"),
                        ),
                        TextField(
                          onChanged: (value) {
                            setState(() {
                              description = value;
                            });
                          },
                          decoration: InputDecoration(hintText: "글 내용"),
                        ),
                        Center(
                            child: ElevatedButton(
                                onPressed: () {
                                  Navigator.of(context).pop();
                                  setState(() {
                                    todos.add(Todo(
                                        title: title,
                                        description: description));
                                  });
                                },
                                child: Text(" 추가 하기")))
                      ],
                    );
                  },
                );
              },
              icon: Icon(Icons.add))
        ],
      ),
      body: ListView.builder(
        itemBuilder: (_, index) {
          return InkWell(
            child: ListTile(
              title: Text(todos[index].title),
              subtitle: Text(todos[index].description),
            ),
          );
        },
        itemCount: todos.length,
      ),
    );
  }
}
반응형

+ Recent posts