[Flutter] 모바일 앱 개발 : Flutter 시작하기 #3 - First Flutter App (2)

in #dclick6 years ago (edited)


안녕하세요. @anpigon 입니다.

이전 글 "모바일 앱 개발 : Flutter 시작하기 #2 "에서 이어지는 내용입니다. Flutter 튜토리얼 파트1의 5~7번까지의 과정을 따라하면서 정리하였습니다. 이번에는 Stateful 위젯과 무한 스크롤 ListView를 구현하는 방법을 학습합니다.

원문을 보고 싶으면 아래 링크를 클릭하세요.
https://codelabs.developers.google.com/codelabs/first-flutter-app-pt1/#0




Stateful 위젯 추가하기

이번 단계에서 우리는 stateful 위젯인 RandomWords를 추가할 것이다. 이 RandomWords는 State 클래스인 RandomWordsState를 생성한다. 그 다음에는 RandomWords를 MyApp Stateless 위젯의 child로 사용할 것이다.

Stateless 위젯은 immutable이다. 그래서 Stateless 위젯의 모든 속성값은 변경할 수 없다. 참고로 앞에서 우리는 MyApp 클래스를 Stateless 위젯을 확장하여 구현하였다.

하지만 Stateful 위젯은 유지되는 동안 변경될 수 있는 상태를 유지한다. Stateful 위젯을 구현하기 위해서는 최소 2개의 클래스가 필요하다. State 클래스State 클래스의 인스턴스를 생성하는 StatefulWidget 클래스이다 . StatefulWidget 클래스는 그 자체로 immutable이지만, State 클래스는 위젯이 유지되는 동안 없어지지 않는다.

Stateless와 Stateful 위젯은 텍스트 설명만 보고는 이해하기가 어렵다. 하지만 앞으로도 계속 있을 튜토리얼을 따라서 구현하다 보면 저절로 이해가 될 것이다.


우선 간단한 State 클래스를 먼저 만들어보자. 외부 파일로 생성해도 되지만 우리는 main.dart 파일에 입력한다. main.dart 파일 맨 아래에 RandomWordsState 클래스를 추가하자.

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

State<RandomWords>는 RandomWords와 같이 사용할 수 있도록 구현된 일반적인 State 클래스를 사용하고 있음을 나타낸다. 대부분 앱의 로직과 상태(state)는 여기에 위치하며, RandomWords 위젯의 상태를 유지한다. RandomWordsState 클래스는 사용자가 스크롤할 때 무한히 생성되는 단어들을 저장한다.


이제 Stateful 위젯인 RandomWords 클래스를 main.dart에 추가하자. 참고로 RandomWords는 RandomWordsState를 생성하는 것 외에는 사용되지 않는다.

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

State 클래스를 추가하고 나면 안드로이드 스튜디오는 클래스에 빌드 메서드(build method)가 누락되어 있다고 알려줄 것이다. 이 메시지는 무시해도 된다.


그다음에는 영어단어를 생성하는 코드를 MyApp 클래스에서 RandomWordsState로 이동하자. 아래와 같이 RandomWordsState에 영어단어를 생성하는 build 메서드를 추가한다.

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


그리고 MyApp 클래스에서는 영어단어를 생성하는 코드를 제거한다.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final WordPair wordPair = new WordPair.random();  // Delete this line.

    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Welcome to Flutter'),
        ),
        body: new Center(
          //child: new Text(wordPair.asPascalCase), // Change this line to... 
          child: new RandomWords(),                 // ... this line.
        ),
      ),
    );
  }
}


코드를 수정하고 나면 앱이 자동으로 새로 고침(Hot reload)이 된다. 만약 자동 새로 고침이 되지 않는다면 앱을 중지하고 다시 시작해보자.




무한 스크롤 ListView 만들기

RandomWordsState 클래스를 확장하여 무한 스크롤되는 단어 목록을 생성해보자. 사용자가 스크롤링하면 ListView 위젯에 표시된 단어 목록이 무한으로 증가할 것이다. ListView의 builder 팩토리 생성자를 사용하면 목록 뷰를 필요할 때에 지연 생성 할 수 있다.

단어 목록을 저장할 _suggestions 변수를 RandomWordsState 클래스에 추가한다 . 그리고 글꼴을 크게 만드는 텍스트 스타일 _biggerFont도 추가한다.

class RandomWordsState extends State<RandomWords> {
  // Add the next two lines.
  final List<WordPair> _suggestions = <WordPair>[];
  final TextStyle _biggerFont = const TextStyle(fontSize: 18.0); 
  ...
}

Dart에서는 변수 앞에 밑줄(_)을 붙이면 privacy이 적용된다.


그다음에는 _buildSuggestions() 메서드를 RandomWordsState 클래스에 추가한다 . 이 메서드는 단어 목록을 표시하는 ListView를 빌드할 것이다.

ListView 클래스는 builder 속성으로 팩토리 빌더 및 콜백 함수인 itemBuilder를 제공한다. 이 함수에는 두 개의 매개 변수 BuildContextrow iterator가 전달된다. iterator는 0부터 시작하여 함수가 호출 될 때마다 매번 증가한다. 이 모델이 무한 스크롤을 가능하게 한다.

아래와 같이 RandomWordsState 클래스에 _buildSuggestions 함수를 추가한다.

  Widget _buildSuggestions() {
    return new ListView.builder(
      padding: const EdgeInsets.all(16.0),
      
      // itemBuilder 콜백은 생성된 단어마다 한 번씩 호출되고 각 단어를 ListTile row에 배치한다.
      // 짝수 행의 경우 이 함수는 단어에 대한 ListTile row를 추가한다.
      itemBuilder: (BuildContext _context, int i) {
      
        // 홀수 행의 경우 구분선(Divider) 위젯을 추가한다.
        if (i.isOdd) {
          return new Divider();
        }

        // 코드 "i ~/ 2"는 i를 2로 나눈 몫을 반환한다.
        // 예를 들면, 1, 2, 3, 4, 5는 0, 1, 1, 2, 2이 된다.
        // Divider 위젯을 제외한 ListView의 실제 단어 수를 계산하기 위함이다.
        final int index = i ~/ 2;
        
        // 사용 가능한 단어 목록이 끝나면 ...
        if (index >= _suggestions.length) {
          // ... 단어 10개를 더 생성하고 단어 목록에 추가.
          _suggestions.addAll(generateWordPairs().take(10));
        }
        return _buildRow(_suggestions[index]);
      }
    );
  }

_buildSuggestions 함수는 단어마다 한 번씩 _buildRow 함수를 호출한다.


RandomWordsState에 _buildRow 함수를 추가하자.

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


이제 RandomWordsState의 _buildSuggestions() 함수를 호출하도록 수정한다.

  @override
  Widget build(BuildContext context) {
    //final wordPair = new WordPair.random(); // Delete these... 
    //return new Text(wordPair.asPascalCase); // ... two lines.

    return new Scaffold (                   // Add from here... 
      appBar: new AppBar(
        title: new Text('Startup Name Generator'),
      ),
      body: _buildSuggestions(),
    );                                      // ... to here.
  }

여기서 Scaffold는 기본 머티리얼 디자인의 시각적 레이아웃을 구현한다.


마지막으로 MyApp의 titlebuild() 함수를 수정하자. 아래와 같이 RandomWords 위젯의 home 부분을 new RandomWords()로 수정한다.

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Startup Name Generator',
      home: new RandomWords(),
    );
  }


앱이 새로 고침이 되고 나면 아래 화면과 같이 무한 스크롤이 작동할 것이다.


만약 앱이 제대로 작동하지 않는다면 lib/main.dart 코드를 참고하세요.

여기까지 읽어주셔서 감사합니다.


divider2461548_1280cutout.png

이전 글

divider2461548_1280cutout.png


Sponsored ( Powered by dclick )
구글 코리아, 페이스북 국내 매출을 사장이 모른다?

오늘 국감장에 나온 구글코리아 존리 대표가 국감장에 출석해서 국내 매출 정보를 알려줄 수 없다...

logo

이 글은 스팀 기반 광고 플랫폼
dclick 에 의해 작성 되었습니다.

Sort:  

흑흑..이제야 제가 공부하는 파이썬 글을 다른분들이 어떤 눈으로 보고 있는지 이해가 됩니다. 슬프군요.

삼행시는 여기에 남겨드립니다 ^^ (다른 분이 보면 부끄러워서 ㅎㅎㅎ)

안되는 일은 없다. 개발자들의..
피와 땀을 갈아 넣는다면.. 모두가
곤히 잠든밤. 코딩을 한다. 나는 안피곤..하..아..ㄹ..ㄲ...ㅏ...?

삼행시 감사합니다~
그리고 파이썬 강좌 잘보고 있습니다.
차트를 볼줄 몰라서 아직은 많이 어렵네요.ㅋ

flutter는 web으로 재활용할수도 있게 되어 있는건가요? (약간 react가 web을 app에서 재활용하는것처럼?)

Flutter는 Dart 언어로 개발합니다. 그런데 Dart 언어 자체가 TypeScript처럼 JavaScript 컴파일러 언어입니다. 하지만 web으로 재활용할 수 있다고 말하기는 어렵네요. 정확하게 말하면 React Native와 비슷하다고 볼수 있어요.

native하면서 ios나 android등의 크로스 플랫폼 정도를 지원하는거군요. 답변 감사합니다.

답변이 되어서 다행입니다. 혹시 플러터에 관심있으면 같이 공부해봐요~ㅋ

올. 뭔가 진행이 되고 계시는군요. ㅎㅎㅎ 저는 내일 올려보도록 하겠습니다.

내일은 어떤 재미있는 개발글이 올라올지 기대됩니다.ㅋ

코딩글은 생각해봤는데 가독성이 넘 떨어져서 아쉽네요

syntax highlight 기능만 좀 더 추가해줘도 좋을텐데

그냥 보자니 눈아프고 핵심코드도 눈에 안들어오구 ㅜㅜ

그렇다고 이미지 캡춰해서 올리기도 그렇고

흠...

안피곤님의 글은 늘 감사합니다. ㅋ 그냥 스팀잇의 지원이 아쉬워서 투정좀 부렸네요.

저는 올초에 티스토리 블로그에서 다른 블로그로 넘어갈려고 마음먹고 워드프레스, 미디엄, 고스트, 깃허브+지킬 등 여러가지 서비스들을 알아봤었어요.
스팀잇은 글쓰기도 불편하고 디자인도 별로고 가독성이 많이 떨어져서 우선순위가 제일 하위였는데..
그런데 하다 보니 스팀잇에 글을 올리고 있네요.ㅋㅋㅋ

참 그리고 물어보고 싶은게 있는데...
스팀잇을 플러터앱으로 구현하셨다고 했었는데, 마크다운 파싱이랑 포스트키로 서명은 어떻게 했나요? 플러터로 앱을 구현하다보니 여기서 막혔네요.ㅠㅠ

툴 개발환경속도는 어때요.
코딩하고 시뮬레이터로 출력하기 까지 속도는 어떤지 궁금하네요

초반 빌드 시간이 조금 있지만, 안드로이드보다는 빠른것 같습니다.
그리고 hot reload 덕분에 코딩하면서 결과를 바로바로 확인할 수 있습니다.

하지만 저는 아직은 리액트 네이티브 보다 좋은 점은 느끼지 못하였습니다. 아직 Dart가 익숙하지 않아서 그런것 같아요.

flutter로 만든 한국 앱 예시중에, 택시 리뷰앱이 있어요. 지난 세종대에서 발표했던 분께서 예시로 도전해서 만드셨는데, 어느 수준으로 앱이 만들어지는지 테스트는 완료됐는데, 택시 리뷰자체가 업데이트 안되서... 외롭고 쓸쓸하게.. 플레이스토어를 지키고 있어요.ㅠㅠ

벌써 국내에서 flutter로 만든 앱이 있었군요. 한번 찾아봐야겠어요.
저도 열심히 분발해서 구글스토어에 앱을 한번 출시해봐야겠어요.
혼자 외롭게 구글스토어에 계시니 저도 같이 있어드려야죠.ㅋㅋ

ㅋㅋ 앱 링크는 요기에요. 이번주 인쇄소가면 마감 얼추 마무리되니까, 연락드리고 또 밥먹으러 갈께요!ㅋㅋ 행사 땜에 들리러 가야해서..ㅎㅎ
https://play.google.com/store/apps/details?id=com.yourcompany.taxidrivers

링크 감사합니다. 설치해봐야겠어요.ㅋ
오늘 편안한 밤되세요~^^

Congratulations @anpigon! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

Award for the number of comments received

Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word STOP

Do not miss the last post from @steemitboard:

SteemitBoard Ranking update - Steem Power, Followers and Following added

Support SteemitBoard's project! Vote for its witness and get one more award!

이거는 몇편까지 연재할 생각이세요?
대충 끝날때쯤 벼락치기로 하고 싶은데....ㅋㅋㅋ

저도 연재가 몇편까지 될지 잘 모르겠어요~
가능하면 https://flutter.io/docs/ 문서는 다 읽어고 정리해봐야죠.ㅋㅋ

@anpigon님 곰돌이 자다 깨서 보팅 왔어요. 그럼 전 다시 꿈나라로~ @gomdory 곰도뤼~

잘은 모르겠지만 ㅋㅋ 언젠간 알게 되겠죠
ㅎㅎ 이번주에는 공부를 할수 있을지 모르겠어요 ㅠㅠ

하다보면 언젠가는 알게됩니다.ㅎ 공부는 스트레스 받지 않는 선까지~

Coin Marketplace

STEEM 0.19
TRX 0.14
JST 0.029
BTC 66425.17
ETH 3185.93
USDT 1.00
SBD 2.63