create account

[flutter] 플러터로 첫번째 앱 만들기 by wonsama

View this thread on: hive.blogpeakd.comecency.com
· @wonsama · (edited)
$5.29
[flutter] 플러터로 첫번째 앱 만들기
![](https://steemitimages.com/640x0/https://cdn.steemitimages.com/DQmdTnqpPybw54uskKRbEqPhWDaZhiyZuimU9J3feyNuGdZ/%E1%84%89%E1%85%B3%E1%84%90%E1%85%B5%E1%86%B7%E1%84%8B%E1%85%B5%E1%86%BA%E1%84%91%E1%85%AD%E1%84%8C%E1%85%B5_190409.002.jpeg)

> 출처 : https://codelabs.developers.google.com/codelabs/first-flutter-app-pt1/#0

# 1. 소개
 
* 플러터는 iOS 및 Android 둘다 개발 할 수 있는 구글의 모바일 SDK 입니다.
* 플러터는 무료며 오픈소스 입니다.
* 객체 지향 코드 및 기본 프로그래밍에 대해 알고 있다면 좀 더 손쉽게 접근 할 수 잇습니다.
* 다트 또는 모바일 프로그래밍에 대한 경험이 없어도 시작하실 수 있습니다.

## 1.1. part 1 에서 배우는 것들

* 플러터 앱을 iOS / Android 처럼 보이게 작성하는 방법
* 플러터 앱의 기본 구조
* 기능 확장을 위한 패키지 검색 및 사용방법
* 핫 리로드를 활용하여 개발 주기를 단축하는 방법
* 스테이트풀 위젯 구현하기
* 데이터가 느리게 로딩되는 무한 목록 만드는 방법

## 1.2. 만드려는 플러터 앱의 목표

* 무한 스크롤
* 스크롤 시 하위 데이터가 로딩이 된 이후 목록을 표시해 주도록 함

## 1.3. 개발환경 설정

> 개발 환경이 구성되지 않은 경우, 링크를 클릭하여 관련 정보를 확인 바랍니다.

* [Flutter SDK](https://flutter.io/get-started/install/) 설치
* [Editor](https://flutter.io/get-started/editor/) 설치
* 디바이스 ( [Android](https://flutter.io/setup-macos/#set-up-your-android-device), [iOS](https://flutter.io/setup-macos/#deploy-to-ios-devices) ) 준비하기 
* [iOS](https://flutter.io/setup-macos/#set-up-the-ios-simulator) 시뮬레이터 준비하기 ( XCode 설치를 필요로 합니다 )
* [Android](https://flutter.io/setup-macos/#set-up-the-android-emulator) 시뮬레이터 준비하기 ( Android Studio 설치를 필요로 합니다 )

## 1.4. 플러터 앱 만들기

> IDE 에서 "New Flutter Project" 메뉴가 보이지 않는 경우 [plugin](https://flutter.io/get-started/editor/#androidstudio) 을 설치 하시기 바랍니다.

* vscode 에서는 플러그인 설치 후 shift + cmd + p 버튼을 누른 이후 타이핑 하면 `New Flutter Project` 를 확인 할 수 있습니다.
* AndroidStudio 에서는 플러그인을 설치 후 메뉴가 생성됨

#### 기본 소스코드 (Hello world)

> 아래 코드를 변형하면서 작업을 진행할 예정 입니다.

#### TIP : 코드 정리하기

> 개발하다 보면 글의 간격이(줄맞춤) 어긋나서 코드의 가독성이 떨어지는데, 이때 Android Studio/IntelliJ IDEA 에서는 우클릭 후 `Reformat Code with dartfmt`, vscode 에서는 우클릭 후 `Format Document`, terminal 에서는 `flutter format <filename>` 을 입력하면 코드가 정렬되는 것을 확인할 수 있습니다.

## 1.5. 기본 소스

```dart
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Welcome to Flutter'),
        ),
        body: const Center(
          child: const Text('Hello World'),
        ),
      ),
    );
  }
```

![](https://cdn.steemitimages.com/DQmTZuAyRzcCcqJzMnotdcLT3TVJXXcQE39ByijKYAuVFSe/image.png)

## 1.6. 살펴보기

* [Material](https://material.io/guidelines/)은 모바일 웹 표준 디자인 언어 입니다. 플러터는 다양한 Material 위젯을 제공 합니다.
* `=>` 화살표 함수를 활용하여 코드를 간결하게 줄일 수 있습니다.
* 플러터에서 대부분의 위젯은 정렬, 패딩, 레이아웃 속성을 포함하고 있습니다.
* 머티리얼 라이브러리의 `Scaffold` 위젯은 기본 앱 바, 제목 및 홈 스크린의 위젯 트리를 포함하는 본문 속성을 제공합니다. 위젯 하위 트리는 상당히 복잡 할 수 있습니다. (우선적으로 필요 속성부터 배워나가면 좋아요)
* 위젯의 주된 임무는 다른 하위 레벨 위젯의 관점에서, 위젯을 표시하는 방법을 설명하는 `build` 메소드를 제공하는 것입니다.

# 2. 외부 패키지 사용하기

* [english_words](https://pub.dartlang.org/packages/english_words) 라는 영단어를 제공해주는 무료 오픈소스 패키지를 사용해 보겠습니다.
* [Pub Site](https://pub.dartlang.org/flutter/) 에 접속해서 다양한 flutter 기반 패키지를 검색 할 수 있습니다.

## 2.1. 패키지 정보를 추가

> `pubspec.yaml` 파일을 열어 패키지 정보를 추가 합니다.

```yaml
dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^0.1.2
  english_words: ^3.1.0   # 이 라인을 추가하면 됩니다.
```

## 2.2. 의존성 다운로드

> `packages get` 명령을 통해 추가된 의존성(dependencies) 정보를 다운로드 합니다.

```sh
flutter packages get
Running "flutter packages get" in startup_namer...
Process finished with exit code 0
```

## 2.3. 소스 import 추가

> 소스(`lib/main.dart`) 상단에 패키지 정보를 추가 합니다.

```dart
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';  // 이 라인 추가
```

## 2.4. 최종 소스

> 실행 할 때 마다 (hot deploy) 중앙의 단어가 변경되는 것을 확인할 수 있습니다

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final wordPair = WordPair.random(); // Add this line.
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
          //child: Text('Hello World'),   // Replace this text...
          child: Text(wordPair.asPascalCase),  // With this text.
        ),
      ),
    );
  }
}
```

![](https://cdn.steemitimages.com/DQmQtfo8b3MkxVuSo1wLJLFR5taa2zsNa8LVLCwrt1ycVwZ/image.png)

# 3. StatefulWidget(상태 변화 있는 위젯) 추가하기 

* `StatelessWidget` 은 변경할 수 없으므로 해당 속성을 변경할 수 없습니다.
* `StatefulWidget` 은 위젯의 수명 기간 동안 변경 될 수 있는 상태를 유지 합니다.
* 이번엔 Stateful 클래스 인 RandomWordsState를 생성 및 활용해 보도록 하겠습니다.
* State 만들기 => StatefulWidget 만들기

## 3.1. 상태 클래스 최소 버전

> `State<RandomWords>` RandomWords 클래스에서 사용하는 상태(State)를 구현한 클래스 입니다.

```dart
class RandomWordsState extends State<RandomWords> {
  // TODO Add build method
}
```

## 3.2. StatefulWidget 만들기

> `StatefulWidget` 위젯을 상속받아 클래스를 만들고, 상태변화를 담당할 클래스(`RandomWordsState`)를 지정 합니다.

```dart
class RandomWords extends StatefulWidget {
  @override
  RandomWordsState createState() => RandomWordsState();
}
```


## 3.3. 상태 구현

> `RandomWords` 클래스에서 상태가 변화하면 `build` 구문을 자동적으로 수행

```dart
class RandomWordsState extends State<RandomWords> {
  @override                                  // Add from this line ... 
  Widget build(BuildContext context) {
    final WordPair wordPair = WordPair.random();
    return Text(wordPair.asPascalCase);
  }                                          // ... to this line.
}
```

## 3.4. 최종 소스

> 이전과 비교해 보면 main에서 랜덤 단어를 생성한 것을 `StatefulWidget` RandomWords 에 위임하여 값을 생성 및 관리하도록 하여, 좀더 유연한(확장하기 쉬운) 소스로 되었습니다.

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
  return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
          child: RandomWords(),
        ),
      ),
    );
  }
}

class RandomWordsState extends State<RandomWords>{
  @override
  Widget build(BuildContext context) {
    final WordPair wordPair = WordPair.random();
    return Text(wordPair.asPascalCase);
  }
}

class RandomWords extends StatefulWidget {
  @override
  RandomWordsState createState() => RandomWordsState();
}
```

# 4. 무한 스크롤 만들기 

> ListView 의 factory build 생성자를 사용하여, 스크롤 할 때 목록을 느리게 빌드 할 수 있습니다. (필요 시 목록을 동적으로 생성하므로 효율적)

* [참조] `_` (언더스코어) 로 시작하면 dart 언어에서는 private 으로 인식하게 됩니다.

## 4.1. 값 추가

> 단어 목록 정보와, 텍스트 스타일을 추가 합니다

```dart
class RandomWordsState extends State<RandomWords> {
  // 아래 두 라인 추가
  final List<WordPair> _suggestions = <WordPair>[];
  final TextStyle _biggerFont = const TextStyle(fontSize: 18); 
  ...
}
```

## 4.2. 목록(ListView.builder) 만들기

```dart
Widget _buildSuggestions() {
    return ListView.builder(
        padding: const EdgeInsets.all(16),

        // itemBuilder는 대상 아이템을 만들어주는 역할을 합니다.
        // 인덱스가 홀수냐 짝수냐에 따라 대상 항목(ListTile)을 보여주거나 구분선(Divider)을 보여줍니다.
        itemBuilder: (BuildContext _context, int i) {
          // 인덱스가 홀수인  경우 구분선을 보여준다
          if (i.isOdd) {
            return Divider();
          }

          final int index = i ~/ 2; // 나누기를 하면 double 임 하지만 ~/ 연산자를 통해 int로 바꿔준다 == (a / b).truncate().toInt() 와 동일한 값 임.

          // i : itemBuilder 내부에 들어가는 실제 항목의 index 값
          // index : i를 2로 나눈 값 ( 홀수 라인에 구분선이 들어가기 때문 )
          // 목록이 증가한 경우에만 값을 더 추가하는 엑션을 처리, 이미 추가한 값은 더이상 추가하지 않음
          // print('$i ::: $index');
          if (index >= _suggestions.length) {
            // index 값이  _suggestions 길이보다 커지는 경우
            _suggestions.addAll(generateWordPairs()
                .take(10)); // 단어 목록에서 10개를 _suggestions 목록 정보에 추가한다
          }

          // item 인덱스(i)가 짝수인 경우에는 해당 _suggestions 인덱스(index)에 값을 보여주도록 한다
          return _buildRow(_suggestions[index]);
        });
  }
```

## 4.3. Row (ListTile) 만들기

```dart
Widget _buildRow(WordPair pair) {
    return ListTile(
      title: Text(
        pair.asPascalCase,
        style: _biggerFont,
      ),
    );
  }
```

![](https://cdn.steemitimages.com/DQmQ8y7aknff4bLSuTkTReLGRWcoSWVVSM2K6Y2QgdHtdom/image.png)

# 5. 기타 참조

* [vs code 소개 동영상](https://code.visualstudio.com/docs/getstarted/introvideos)

# 맺음말 

* 4개로 나눠서 하려다가 그냥 한개로 만들었네요 
* 실제 하나하나 따라가면서 학습하면서 하니 시간이 좀 걸리네요 후...
* 궁금한 것은 언제든지 댓글 문의 바랍니다.
👍  , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , and 182 others
properties (23)
authorwonsama
permlinkflutter
categorykr
json_metadata{"tags":["kr","kr-dev","jjm","mini","busy"],"image":["https://steemitimages.com/640x0/https://cdn.steemitimages.com/DQmdTnqpPybw54uskKRbEqPhWDaZhiyZuimU9J3feyNuGdZ/%E1%84%89%E1%85%B3%E1%84%90%E1%85%B5%E1%86%B7%E1%84%8B%E1%85%B5%E1%86%BA%E1%84%91%E1%85%AD%E1%84%8C%E1%85%B5_190409.002.jpeg","https://cdn.steemitimages.com/DQmTZuAyRzcCcqJzMnotdcLT3TVJXXcQE39ByijKYAuVFSe/image.png","https://cdn.steemitimages.com/DQmQtfo8b3MkxVuSo1wLJLFR5taa2zsNa8LVLCwrt1ycVwZ/image.png","https://cdn.steemitimages.com/DQmQ8y7aknff4bLSuTkTReLGRWcoSWVVSM2K6Y2QgdHtdom/image.png"],"app":"busy/2.5.6","format":"markdown","community":"busy","users":[],"links":[]}
created2019-05-10 06:49:57
last_update2019-05-10 06:55:00
depth0
children9
last_payout2019-05-17 06:49:57
cashout_time1969-12-31 23:59:59
total_payout_value4.040 HBD
curator_payout_value1.245 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length8,415
author_reputation157,263,627,541,921
root_title"[flutter] 플러터로 첫번째 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id84,588,855
net_rshares10,174,025,218,248
author_curate_reward""
vote details (246)
@anpigon ·
원사마님 플러터 진도가 넘 빨라요.😀👍
properties (22)
authoranpigon
permlinkre-wonsama-flutter-20190511t031603046z
categorykr
json_metadata{"tags":["kr"],"app":"steemit/0.1"}
created2019-05-11 03:16:03
last_update2019-05-11 03:16:03
depth1
children0
last_payout2019-05-18 03:16:03
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length21
author_reputation17,258,940,000,931
root_title"[flutter] 플러터로 첫번째 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id84,642,941
net_rshares0
@fur2002ks ·
헉~~~~ 또 피곤!! ㅋㅋ 즐거운 불금 되세요^^
properties (22)
authorfur2002ks
permlinkre-wonsama-flutter-20190510t070955355z
categorykr
json_metadata{"tags":["kr"],"app":"steemit/0.1"}
created2019-05-10 07:10:00
last_update2019-05-10 07:10:00
depth1
children3
last_payout2019-05-17 07:10:00
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length28
author_reputation215,309,454,101,823
root_title"[flutter] 플러터로 첫번째 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id84,590,007
net_rshares0
@wonsama · (edited)
안피곤님이 출동 할 것입니다 / 즐거운 주말 보내세요~~  [@anpigon](https://steemit.com/@anpigon)
👍  
properties (23)
authorwonsama
permlinkwonsama-re-fur2002ks-re-wonsama-flutter-20190510t071046365z
categorykr
json_metadata{"app":"partiko","client":"android"}
created2019-05-10 07:10:48
last_update2019-05-10 07:11:27
depth2
children2
last_payout2019-05-17 07:10:48
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length73
author_reputation157,263,627,541,921
root_title"[flutter] 플러터로 첫번째 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id84,590,054
net_rshares17,415,921,962
author_curate_reward""
vote details (1)
@fur2002ks ·
ㅋㅋㅋ 지난번 처럼 또 안피곤~ 댓글 다실듯...
properties (22)
authorfur2002ks
permlinkre-wonsama-wonsama-re-fur2002ks-re-wonsama-flutter-20190510t072116523z
categorykr
json_metadata{"tags":["kr"],"app":"steemit/0.1"}
created2019-05-10 07:21:21
last_update2019-05-10 07:21:21
depth3
children1
last_payout2019-05-17 07:21:21
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length27
author_reputation215,309,454,101,823
root_title"[flutter] 플러터로 첫번째 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id84,590,682
net_rshares0
@jerdep ·
Thank you for your continued support towards JJM. For each 1000 JJM you are holding, you can get an additional 1% of upvote. 10,000JJM would give you a 11% daily voting from the 600K SP virus707 account.
properties (22)
authorjerdep
permlinkre-flutter-1557491178
categorykr
json_metadata{"tags":["jjm"]}
created2019-05-10 12:27:12
last_update2019-05-10 12:27:12
depth1
children0
last_payout2019-05-17 12:27:12
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length203
author_reputation230,648,501,944
root_title"[flutter] 플러터로 첫번째 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id84,604,211
net_rshares0
@noisysky ·
오 관심있는데 좋은 포스팅감사합니다.
한번 해봐야겠어요~
properties (22)
authornoisysky
permlinkre-wonsama-flutter-20190510t071247535z
categorykr
json_metadata{"community":"busy","app":"busy/2.5.6","format":"markdown","tags":["kr"],"users":[],"links":[],"image":[]}
created2019-05-10 07:12:51
last_update2019-05-10 07:12:51
depth1
children1
last_payout2019-05-17 07:12:51
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length31
author_reputation121,614,427,100,064
root_title"[flutter] 플러터로 첫번째 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id84,590,186
net_rshares0
@wonsama ·
넵 :) 즐거운 코딩 라이프 즐기세여 ~
👍  
properties (23)
authorwonsama
permlinkre-noisysky-re-wonsama-flutter-20190510t071611018z
categorykr
json_metadata{"tags":["kr"],"app":"steemit/0.1"}
created2019-05-10 07:16:12
last_update2019-05-10 07:16:12
depth2
children0
last_payout2019-05-17 07:16:12
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length22
author_reputation157,263,627,541,921
root_title"[flutter] 플러터로 첫번째 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id84,590,392
net_rshares17,771,935,792
author_curate_reward""
vote details (1)
@virus707 ·
Thank you for your continued support towards JJM. For each 1000 JJM you are holding, you can get an additional 1% of upvote. 10,000JJM would give you a 11% daily voting from the 600K SP virus707 account.
properties (22)
authorvirus707
permlinkre-flutter-1557497598
categorykr
json_metadata{"tags":["jjm"]}
created2019-05-10 14:13:12
last_update2019-05-10 14:13:12
depth1
children0
last_payout2019-05-17 14:13:12
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length203
author_reputation557,563,606,581,756
root_title"[flutter] 플러터로 첫번째 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id84,609,779
net_rshares0