Flutter 사용기 2

like0·2022년 3월 22일
0

Getting started
해당 링크까지는 완료된 상태에서 이번 연습을 해보았다.

튜토리얼

Write Your First Flutter App, part 1

📌 Stateful widget 그리고 Stateless widget

  • stateless widget은 변경할 수 없다. (all values are final)

  • stateful widget은 변경될 수 있는 상태를 유지한다.

  • stateful widget을 구현하는데 적어도 2개의 class가 필요하다.
    - a StatefulWidget class (state class의 instance를 만든다.)
    - a State class

Step 1: Create the starter Flutter app

lib/main.dart의 코드를 수정해준다.

Step 2: Use an external package

해당 프로젝트에서는 english_words package가 필요하다.
튜토리얼에서 소개하는 순서대로 진행한다.

Step 3: Add a Stateful Widget

RandomWords (stateful widget)과 _RandomWordsState(state widget) 를 추가한다. (RandomWords가 state class인 _RandwomWords class를 만든다.)

RandomWords class는 MyApp(stateless) 내에서 child로서 사용할 수 있다.

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

  @override
  _RandomWordsState createState() => _RandomWordsState();
}

class _RandomWordsState extends State<RandomWords> {
  @override
  Widget build(BuildContext context) {
     final wordPair = WordPair.random();
     return Text(wordPair.asPascalCase);
  }
}
//build 함수 업데이트 하였다.

Step 4: Create an infinite scrolling ListView


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

  @override
  State<RandomWords> createState() => _RandomWordsState();
}

class _RandomWordsState extends State<RandomWords> {
  final _suggestions = <WordPair>[];
  final _biggerFont = const TextStyle(fontSize: 18.0);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Startup Name Generator'),
      ),
      body: ListView.builder( 
        padding: const EdgeInsets.all(16.0),
        itemBuilder: /*1*/ (context, i) { 
          if (i.isOdd) return const Divider(); /*2*/

          final index = i ~/ 2; /*3*/
          if (i >= _suggestions.length) {
            _suggestions.addAll(generateWordPairs().take(10)); /*4*/
          }
          return ListTile(
            title: Text(
              _suggestions[i].asPascalCase,
              style: _biggerFont,
            ),
          );
        },
      ),
    );
  }
}

나는 inifinite item을 위해 ListView.builder를 사용한다고 이해했다.
/1/

  • itemBuilder는 callback함수이다. (ListView나 flutter framework는 무언가 보여줄 것이 있을 때마다 itemBuilder를 호출한다.- callback 함수가 실행되는 시점)

  • i는 wordPairing에 대해 2번 증가한다. (한번은 ListTile, 또 다른 한번은 Divider에 대해)

/2/

  • i가 홀수일 때는 함수는 Devider widget을 추가한다. (이것은 화면에 보여지는 선을 나타낸다.)

/3/

  • 2로 나누는 이유는 wordPairing 중에서 divider widget을 제외한 실제 숫자를 계산하기 위함이라고 이해했다.

/4/

  • 사용 가능한 wordPairing의 끝에 다다르면 10개를 더 생성하고 suggestionslist에 추가한다.

Write Your First Flutter App, part 2

아이콘 추가하고, interactivity 추가, 새로운 페이지 (플러터에서는 route라고 부른다) 와 기존 페이지를 연결하기를 구현해본다.

Step 1-3 은 set up 과정

Step 4 : Add icons to the list

  • _RandomWordsState에 _saved Set 추가
final _saved = <WordPair>{};     // NEW
  • pair이 _save에 존재하는지 확인하기 위해 alreadySaved 변수 추가
 final alreadySaved = _saved.contains(pair);  // NEW
  • alreadySaved 값에 따라 아이콘 모양과 색을 정한다.
trailing: Icon(     // NEW from here...
      alreadySaved ? Icons.favorite : Icons.favorite_border,
      color: alreadySaved ? Colors.red : null,
      semanticLabel: alreadySaved ? 'Remove from saved' : 'Save',
    ),  


아직 interactivity는 추가되지 않았다.

Step 5: Add interactivity

이 단계에서는 하트 아이콘을 탭으로 만든다. 사용자가 목록의 엔트리를 탭하여 원하는 상태로 전환하면 해당 word pairing이 _saved set에 추가 또는 삭제된다.

  • onTap 추가
onTap: () {      // NEW lines from here...
      setState(() {
        if (alreadySaved) {
          _saved.remove(pair);
        } else { 
          _saved.add(pair); 
        } 
      });
    }, 

Step 6: Navigate to a new screen

새로운 페이지를 추가한다. (flutter에서는 route라고 부른다.)
route간에 이동함을 연습해본다.

Navigator는 앱의 route를 포함하는 스택을 관리한다.
route를 네비게이터 스택에 푸시하면 해당 route로 표시가 업데이트된다.
Navigator stack에서 pop하면 이전 route로 돌아간다.

  void _pushSaved() {
    Navigator.of(context).push(
      // Add lines from here...
      MaterialPageRoute<void>(
        builder: (context) {
          final tiles = _saved.map(
            (pair) {
              return ListTile(
                title: Text(
                  pair.asPascalCase,
                  style: _biggerFont,
                ),
              );
            },
          );
          final divided = tiles.isNotEmpty
              ? ListTile.divideTiles(
                  context: context,
                  tiles: tiles,
                ).toList()
              : <Widget>[];

          return Scaffold(
            appBar: AppBar(
              title: const Text('Saved Suggestions'),
            ),
            body: ListView(children: divided),
          );
        },
      ), // ...to here.
    );
  }
Navigator.of(context).push{
	MaterialPageRoute<void>(
		...
	)
}

의 코드를 통해 Navigator에 새로운 route를 push 한다. (예제에서 새로운 route는 하트가 눌려진 이름들을 보여주는 페이지이다.)
새 페이지의 내용은 MaterialPageRoute의 빌더 속성에 익명 함수로 작성된다.
tiles는 ListTile을 리턴하며, _saved 내의 pair를 나타낸다.
divided는 tiles가 비어있다면 빈칸을, 비어있지 않다면 구분선을 나타내는 것으로 이해했다.

profile
배우고 성장하는 개발자가 되기!

0개의 댓글