본문 바로가기
공허의 유산/사상의 도구

[Flutter]. 05. Flutter tutorial on codelab(1)

by 바른생활머시마 2023. 1. 16.
728x90
반응형

Flutter Learn에 소개 된 다음 내용은 codelab이라는 곳에서 진행되는 튜토리얼입니다.

 

https://codelabs.developers.google.com/codelabs/flutter-codelab-first?hl=ko#0 

 

Your first Flutter app  |  Google Codelabs

In this codelab, you’ll learn how to build a Flutter app that generates random, cool-sounding names.

codelabs.developers.google.com

 

이 tutorial에서 만드는 앱은 일종의 이름을 지어주는 앱입니다. 이 과정에서 flutter의 중요한 내용들을 살펴보게 됩니다. 템플릿으로 제공 되었던 샘플 프로젝트 형태(상단 타이틀바 + 내용)를 Scaffold 형태의 UI로 처리하는데 그 상태의 코드로부터 전혀 다른 아래 형태로 어떻게 바꾸는지 배우면 화면에 맞는 구조를 어떻게 잡을지 이해하는데 도움이 될 것 같습니다.

 개발 환경 구축과 템플릿 프로젝트 생성에 대한 내용도 있는데, 이것은 이미 살펴봤기 때문에 넘어가면 되겠네요. 프로젝트 생성 후, 앞에서 설정 파일 같다고 했던 아래 파일에 대한 수정 내용이 있으니, Create project 의 뒷 부분은 살펴보면서 진행 해야 되겠습니다. 지금은 특별한 내용이 없고, 실제 출시를 준비하게 되면 할 것이 많아질 것이라고 하네요.

pubspec.yaml

name: namer_app
description: A new Flutter project.

publish_to: 'none' # Remove this line if you wish to publish to pub.dev

version: 0.0.1+1

environment:
  sdk: '>=2.18.4 <3.0.0'

dependencies:
  flutter:
    sdk: flutter

  english_words: ^4.0.0
  provider: ^6.0.0

dev_dependencies:
  flutter_test:
    sdk: flutter

  flutter_lints: ^2.0.0

flutter:
  uses-material-design: true

 

analysis_optional.yaml

include: package:flutter_lints/flutter.yaml

linter:
  rules:
    prefer_const_constructors: false
    prefer_final_fields: false
    use_key_in_widget_constructors: false
    prefer_const_literals_to_create_immutables: false
    prefer_const_constructors_in_immutables: false
    avoid_print: false

 

 

실제로 작성 할  dart 코드가 주어지는데 50여줄 됩니다.  템플릿 프로젝트 보다는 코드가 더 짧고 간단한 것 같네요.

주요 Class들을 살펴보니 Change Notification도 보이고, StatelessWidget을 상속 받은 앱이 주요 Class인 것 같습니다.

 그 속에는 Scafford가 있는 것을 보니 한방에 다 완성하는 것은 아닌가 봅니다.  tutorial처럼 코드를 수정/입력하여 결과를 한번 보겠습니다. 설명 없이 불쑥 코드가 나와버려서 걱정스러운 분들이 많은지, Note를 달고 혹시 궁금하더라도 조금 기다려 달라고 하네요. 맘 편히 그냥 한번 따라 가 보도록 하겠습니다.

 

 

import 'package:english_words/english_words.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => MyAppState(),
      child: MaterialApp(
        title: 'Namer App',
        theme: ThemeData(
          useMaterial3: true,
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepOrange),
        ),
        home: MyHomePage(),
      ),
    );
  }
}

class MyAppState extends ChangeNotifier {
  var current = WordPair.random();
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var appState = context.watch<MyAppState>();

    return Scaffold(
      body: Column(
        children: [
          Text('A random idea:'),
          Text(appState.current.asLowerCase),
        ],
      ),
    );
  }
}

 

 

 

Add a button

버튼을 추가 할 차례인데, 작성한 코드의 결과를 확인하면서 진행해야 하니, 저는 크롬을 이용해서 하면 좋겠는데, VSCode에서 어떻게 하면 되는지는 앞에 나와 있지 않았어요. Android Studio에서는 Device를 선택 할 수 있었는데, VSCode는 그냥 실행하면 Windows application이 되었어요. 그 내용이 여기 소개 되네요. 화면 우측 하단에서 Device를 선택하면 되네요.

앗~ 그런데 그 이상이 있었군요. Android Studio에서 생성해둔 Virtual Device도 선택 할 수 있군요. 하나 건졌습니다.

 

실행하면 단순한 화면이 나오네요.

 

이어서, Hot Reload를 가장 먼저 해보도록 소개 하며 저장 시점에 적용 되는 것을 강조하고 있네요. 버튼 추가를 하고...

버튼을 누르면 VSCode 아래쪽의 Debug console에 로그가 출력 됩니다. print를 이용해서 디버깅을 할 수 있겠네요.

 

간단히 코드 설명이 되어 있는데요, 한번 살펴 보겠습니다.

 

먼저 app이 실행되는 부분입니다.

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

main 함수에서 runApp이라는 함수를 실행하고 여기에 어떤 클래스 instance를 하나 넘기는 식인 것 같네요.(flutter는 new를 안써도 된다고 하던데 new MyApp() 이런 의미인 것 같습니다.)

 

이어서, 저 MyApp이라는 클래스를 살펴 봅니다. 지금은 잘 모르겠지만,  StatelessWidget을 상속 받았고, build라는 함수를 재정의하면서 Widget을 리턴하도록 했네요. 앞에서는 Scafford였는데 ChangeNotifierProvider라는 새로운 Widget이네요. Scafford는 하위에 포함되어 있군요. context는 뭔지 모르겠지만 전달하고 있고, MaterialApp에 뭔가 많은게 정의 되는 것 같습니다. 제목과 테마를 설정해주네요. 

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

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => MyAppState(),
      child: MaterialApp(
        title: 'Namer App',
        theme: ThemeData(
          useMaterial3: true,
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.green),
        ),
        home: MyHomePage(),
      ),
    );
  }
}

다음으로, 바로 앞에서 context를 넘겨받을 때 사용 된 MyAppSate 클래스인데, 아직은 무슨 말인지 잘 모르겠네요.

class MyAppState extends ChangeNotifier {
  var current = WordPair.random();
}

 

 

flutter의 기본 구조를 소개하기 위해 매우 단순한 예제를 만들었다는데, 뭐 대략 알듯 말듯 하네요. 상태가 변수를 말하는 것 같은데, 저 단어쌍이 변수라서 상태인 것 같은데, 변수가 변경 되는데 왜 Stateless를 상속 받았을까 싶네요.

끝으로, MyAppState에 새로운 함수를 추가하고 이 함수는 새로운 단어쌍을 만들고 변경을 통지하는 코드로 작성합니다.

class MyAppState extends ChangeNotifier {
  var current = WordPair.random();

  // ↓ Add this.
  void getNext() {
    current = WordPair.random();
    notifyListeners();
  }

}

 

버튼이 눌려지면, print를 했었는데, 거기서 추가 된 함수를 실행하여 새로운 단어쌍이 표시 되도록 합니다.

MyAppState는 context를 통한 참조 변수를 가지고 있었고, 이를 통해서 함수를 실행하게 됩니다.

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var appState = context.watch<MyAppState>();

    return Scaffold(
      body: Column(
        children: [
          Text('A random AWESOME idea:'),
          Text(appState.current.asLowerCase),

          // ↓ Add this.
          ElevatedButton(
            onPressed: () {
              print('button pressed!');
              appState.getNext();
            },
            child: Text('Next'),
          ),

        ],
      ),
    );

  }
}

 

 

여기서 더 진도를 나가지 말고, 이벤트가 어디서 어떻게 전달되고, 참조는 어떻게 가지게 되는지 한번 찬찬히 살펴보고 지나가면 좋겠습니다. 다음에는 남은 부분들을 좀 더 살펴보도록 하겠습니다.

 

728x90
반응형

댓글