Write Your First Flutter App

Ashe·2019년 12월 8일
0

잿더미의 Flutter

목록 보기
3/8

원문

Part 1에서 배울 내용

  • IOS와 Android 모두에서 자연스럽게 보이는 Flutter 앱을 작성하는 방법
  • Flutter 앱의 기본 구조
  • 기능을 확장하기 위해 패키지 찾기 및 사용
  • 더 빠른 개발을 위해 핫 리로드 사용
  • 상태를 저장할 수 있는 위젯을 구현하는 방법
  • 무한 스크롤 목록을 작성하는 방법

1부에서 만들 내용

새로운 이름을 마구잡이로 생성하는 모바일 앱을 구현합니다. 사용자는 마음에 드는 이름을 선택해서 저장할 수 있습니다. 이름으 한번에 10개씩 로딩되고 스크롤하면 더 생성됩니다.

Flutter 환경 설정

이 실습을 완료하려면 Flutter SDK편집기 라는 두 가지 소프트웨어가 필요합니다 . Android Studio를 사용하지만 원하는 편집기를 사용해도 됩니다.

다음 장치 중 하나를 사용하여이 예제를 실행할 수 있습니다.

초기 Flutter 앱 실행

여러가지 방법으로 Flutter 프로젝트를 생성할 수 있습니다. 동일하게 실행하기 위해 Terminal로 해보겠습니다.

$ flutter create google_codelab
$ cd google_codelab
$ flutter devices
# No devices dected가 뜨면 에뮬레이터를 띄워야한다.
$ flutter emulators
# 몇가지 가능한 선택지가 있을텐데 그 중 하나를 실행한다.
# 없으면 에뮬레이터를 설치해야한다.
$ flutter emulators --launch ios
$ flutter devices
# 이제 하나 연결 가능한 디바이스가 있을것이다.
$ flutter run

lib/main.dart 편집

lib/maind.dart 의 모든 내용을 아래 내용으로 교체한다.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  
  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'),
        ),
      ),
    );
  }
}

교체한 후 저장을 누르고 터미널에서 r 을눌러 리로딩한다.

코드 관찰

  • 이 예제는 Material App을 만듭니다. 머티리얼은 모바일과 웹에서 표준적인 비주얼 디자인 언어입니다. Flutter는 다양한 머티리얼 위젯을 제공합니다.
  • main method는 화살표 ( => ) 표기법을 사용합니다. 하나의 메서드를 실행할 때는 화살표 표기법으로 단축할 수 있습니다.
  • StatelessWidget을 상속하여 내 앱을 만듭니다. Flutter에서 정렬, 패딩, 레이아웃 등 모든것이 위젯입니다.
  • Material 라이브러리의 Scaffold 위젯은 기본 앱 바, 제목, 홈 화면의 위젯 트리를 보유하는 속성을 제공합니다. 위젯 서브 트리는 입력하는 내용에 따라 상당히 복잡해질 수 있습니다.
  • 위젯의 주요 작업은 build 를 사용하여 하위 위젯들을 표시하는 방법을 제공하는 것입니다.
  • 이 예제의 body는 Center 안에 Text를 포함한 위젯으로 구성됩니다. Center 위젯은 하위 트리를 중앙에 맞춥니다.

외부 패키지 사용

이 단계에서는 english_words 라는 오픈 소스 패키지를 사용합니다 . 여기에는 가장 많이 사용되는 영어 단어 몇 가지와 일부 유틸리티 기능이 포함되어 있습니다.

pub 사이트에서 english_words 이외에 다른 오픈소스 패키지를 확인할 수 있습니다.

pubspec.yaml

이 파일은 현재 프로젝트의 Flutter 앱의 Resource들을 관리합니다.

여기에 우리가 사용할 english_words: ^3.1.0 을 추가합니다.

dependencise:
	flutter:
		sdk: flutter
		
		cupertino_icons: ^0.1.2
		english_words: ^3.1.0  # 이걸 추가해주세요!

Pubspec.yaml에 새 dependencise 를 추가했으면 해당 패키지를 가져와야하기때문에 명령어를 입력해줍니다.

flutter packages get

english_words를 가져오기

새 패키지를 가져와서 사용하기위해 lib/main.dart 파일을 수정합니다. 총 네군데를 변경해줍니다.

import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';  // 여기 추가!

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

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    final wordPair = wordPair.random();  // 여기 추가!
    
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Welcome to Flutter'),
        ),
        body: Center(  // const 삭제!
          child: Text(wordPair.asPascalCase),  // const 삭제, 내용 변경
        ),
      ),
    );
  }
}

앱이 실행중인 경우 Terminal에서 r 버튼을 눌러 수정사항을 적용할 수 있습니다. ( 핫 리로드 기능 ) 핫 리로드를 수행할때마다 임의로 선택된 다른 단어들이 표시됩니다. 그 이유는 MaterialApp이 렌더링을 재 수행할때마다 새 단어쌍이 생성되기 때문입니다.

상태 저장 위젯 추가

Stateless 위젯은 값이 변하지 않는 위젯입니다. 즉, final로 선언된 값입니다.

Statefulwidget은 위젯의 생명주기동안 값이 변할 수 있는 위젯입니다. 구현을 위해서는 반드시 State 인스턴스를 생성하는 StatefulWidget 클래스를 생성해야합니다. StatefulWidget 자체의 값은 변하지 않지만 내부의 State 클래스는 생명주기동안 값이 바뀔 수 있습니다.

  • 이 단계에서는 상태를 저장 위젯인 RandomWordsState를 생성하는 RnadomWords 클래스를 추가합니다. 그 다음 MyApp의 StatelessWidget의 하위 인스턴스로 사용합니다.
class RandomWordsState extends State<RandomWords> {
	// TODO Add build method
}

State<RandomWords> 는 RandomWords와 함께 사용하도록하는 State 클래스를 사용하는 것을 나타냅니다. RandomWords 위젯의 상태를 관리하며 앱의 Logic과 State는 대부분 여기에 존재할 것입니다. 이 클래스는 생성된 단어들과 즐겨찾기들을 저장합니다.

  • Stateful RandomWords 위젯을 main.dart에 추가합니다. RandomWords 위젯은 State 클래스를 생성하는 것 외에는 다른 기능을 거의 수행하지 않습니다.
class RandomWords extends StatefulWidget {
	
	RandomWordsState createState() => RandomWordsState();
}

State 클래스를 추가한 후 IDE에서 build 메서드를 구현하지 않았다고 에러가 뜰것입니다.

  • 단어 생성 코드를 RandomWordsState로 이동하여 단어 쌍을 생성하는 build를 구현합니다.
class RandomWordsState extends State<RandomWords> {
	
	Widget build(BuildContext context) {
		final WordPair wordPair = WordPair.random();
		return Text(wordPair.asPascalCase);
	}
}
  • 그리고 기존의 WordPair 를 생성하는 부분을 삭제하고 RandomWords를 사용하도록 변경합니다.
class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    final WordPair wordPair = WordPair.random();  // 삭제합니다.

    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
          //child: Text(wordPair.asPascalCase), // 이 라인을 삭제하고
          child: RandomWords(),                 // ... 이렇게 변경합니다.
        ),
      ),
    );
  }
}

무한 스크롤 ListView 생성

이 단계에서는 RandomWordsState를 확장하여 단어 목록을 생성하고 표시합니다. 사용자가 스크롤하면 ListView 위젯에 표시되는 목록이 무한대로 보이게됩니다. ListView의 builder 팩토리 생성자를 사용하면 Lazy load 를 구현할 수 있습니다.

  • RandomWordsState 클래스에 _suggestions 은 단어들을 저장하기 위해 사용합니다. 또한 글꼴 크기를 크게하려면 _biggerFont 변수를 추가합니다.
class RandomWordsState extends State<RandomWords> {
	final List<WordPair> _suggestions = <WordPair>[];
	final TextStyle _biggerFont = const TextStyle(fontSize: 18);
  ...
}

TIP: 변수명에 밑줄을 붙이면 Dart 언어로 해당 속성은 프라이빗 변수임을 알립니다.

다음으로, RandomWordsState 클래스에 _buildSuggestions() 함수를 추가합니다. 이 메소드는 단쌍들을 표시하는 ListView를 빌드합니다.

ListView 클래스는 익명의 함수로 지정된 팩토리 빌더 및 콜백 함수인 itemBuilder 를 제공합니다. 두 개의 매개변수(BuildContext 및 반복 변수인 i)가 함수에 제공됩니다. 반복자 i 는 0에서 시작하여 함수가 호출된때마다 하나씩 증가합니다. 이 모델을 사용하면 사용자가 스크롤 할 때 _suggestions 는 무한대로 커질 수 있습니다.

  • RandomWordsState 클래스에 아래와 같이 _buildSuggestions 기능을 추가합니다.
Widget _buildSuggestions() {
	retunr ListView.builder(
		padding: const EdgeInsets.all(16),
		// itemBuilder 콜백은 _suggestions 의 하나당 한 번 호출되며 
		// 각 suggestion을 ListTile에 배치합니다. 
		// 짝수 행의 경우 함수는 단어 쌍을 위한 ListTile 행을 추가합니다. 
		// 홀수 행의 경우, 시각적으로 구분하기 위한 구분자 위젯을 추가합니다. 
		// 소형 장치에서 구분자를 보기 어려울 수 있다는 점에 유의해야합니다.
    itemBuilder: (BuildContext _context, int i) {
      // ListView에 1 px의 구분자를 각 행마다 추가합니다.
      if (i.isOdd) {
        return Divider();
      }
      
      // "i ~/ 2"는 2로나눈 몫을 가져옵니다.
      // 예로: 1, 2, 3, 4, 5 는 0, 1, 1, 2, 2.
      // 홀수번은 Divider가 배치되므로 짝수의 결과를 가져와야합니다.
      final int index = i ~/ 2;
      
      // 만약 _suggestions의 끝에 도달하면
      if (index >= _suggestions.length) {
        // 10개의 아이템을 _suggstions에 추가합니다.
        _suggestions.addAll(generateWordPairs().take(10));
      }
      return _buildRow(_suggestions[index]);
    }
	)
}

_buildSuggestions 함수는 단어당 _buildRow 를 한 번 호출합니다. _buildRow 는 2부에서 더 매력적으로 ListTile을 표시할 수 있습니다.

  • RandomWordsState에 _buildRow 함수를 추가합니다.
Widget _buildRow(WordPair pair) {
	return ListTile(
		title: Text(
			pair.asPascalCase,
			style: _biggerFont,
		)
	)
}
  • 단어 생성 라이브러리를 직접 호출하지 않고 _buildSuggestions() 를 사용하도록 RandomWordsState의 빌드 메서드를 업데이트합니다. (Scaffold 는 기본 메터리얼 디자인 비주얼 레이아웃을 구현합니다.)

Widget build(BuildContext context) {
	  // final wordPair = WordPair.random();  // 삭제합니다.
	  // return Text(wordPair.asPascalCase);  // 삭제합니다.
	  
	  return Scaffold(												// 여기서부터
			appBar: AppBar(
				title: Text('Startup Name Generator'),
			),
			body: _buildSuggestions(),						// 여기까지 추가합니다.
	  )
}
  • MyApp의 빌드 메서드를 업데이트하고 제목을 변경하고 홈을 RandomWords 위젯으로 변경합니다.

Widget build(BuildContext context) {
	return MaterialApp(
		title: 'Startup Name Generator',
		home: RandomWords(),
	)
}
  • 재시작하고 결과를 확인해야합니다.
profile
Qué será, será

0개의 댓글