Write your first Flutter app, part 2
Contents
- 두번째 screen을 만들고 navigation추가.
- icon추가, icon action 추가.
What you’ll build in part 2
오른쪽 이미지의 앱은 Part2에서 우리가 만들 결과물 입니다.
Part1 에서 만들었던 word list에 하트 icon을 넣고 favorite word를 지정합니다.
두번째 page를 만들고, 두번째 페이지와 첫번째 페이지를 이동할 수 있는 navigation을 넣습니다.
두번째 페이지에서 favorite 지정된 word를 보고 favorite 지정된 word를삭제 합니다.
두번째 page에서 삭제된 word는 첫번째 page에도 적용되어야 합니다.
Step 1: List에 하트 icons 추가
이번 과정에서 우리는 하트모양의 아이콘을 추가 해보겠습니다. 클릭하면 favorite 로 지정 또는 삭제(토글) 되는 기능을 넣어보겠습니다.
-
_saved Set을
RandomWordsState
class에 추가 합니다.
이 Set는 favorite 으로 지정된 단어를 저장 합니다. 우리는 이것을 List로 만들어 중복을 허용하지 않을 것입니다.
아래 소스 코드를 참고하여 작성 하세요.class RandomWordsState extends State
{ final List _suggestions = []; final Set _saved = Set (); // Add this line. final TextStyle _biggerFont = TextStyle(fontSize: 18.0); ... } -
_buildRow
function 에 alreadySaved 변수를 추가 합니다. 본 값은 단어가 이미 선택된 것인지 boolean 값으로 저장 합니다.Widget _buildRow(WordPair pair) { final bool alreadySaved = _saved.contains(pair); // Add this line. ... }
_buildRow()
function 하트모양의 icon을 추가 합니다. icon은 ListTile object에 넣습니다.
icon은 flutter에서 기본 제공해주는 것을 사용 합니다.Widget _buildRow(WordPair pair) { final bool alreadySaved = _saved.contains(pair); return ListTile( title: Text( pair.asPascalCase, style: _biggerFont, ), trailing: Icon( // Add the lines from here... alreadySaved ? Icons.favorite : Icons.favorite_border, color: alreadySaved ? Colors.red : null, ), // ... to here. ); }
-
앱에 적용된 모습을 hot-reload 를 통해 확인 합니다.
수정중인 dart 파일을 저장 하거나, run 버튼을 누르면 hot reload 가 됩니다.
아래와 같은 결과물이 나타나면 제대로 진행한 것입니다.Android iOS
Problems?
해결되지 않는 문제가 있다면 아래 완성된 코드를 참고하여 수정 하세요.
- lib/main.dart
-
Step 2: interactivity 추가
-
하트아이콘에 클릭 action을 추가 하여 toggle 되도록 만들겠습니다.
만약 favorite 에 저장된 단어이면 favorite에서 삭제하고 하트 아이콘의 컬러를 없애겠습니다.
favorite에 저장 안되어 있다면 저장하고 하트 아이콘을 빨간색으로 변경 하겠습니다.본 액션을 위해 우리는
_buildRow
function을 수정 합니다. tile(list의 한 row)이 클릭되면setState()
function이 호출되고 state가 변경됨을 알립니다._buildRow
function에 onTap property를 아래 소스 코드를 참고하여 추가 합니다.Widget _buildRow(WordPair pair) { final bool alreadySaved = _saved.contains(pair); return ListTile( title: Text( pair.asPascalCase, style: _biggerFont, ), trailing: Icon( // Add the lines from here... alreadySaved ? Icons.favorite : Icons.favorite_border, color: alreadySaved ? Colors.red : null, ), onTap: () { // Add 9 lines from here... setState(() { if (alreadySaved) { _saved.remove(pair); } else { _saved.add(pair); } }); }, // ... to here. ); }
Tip!!: Flutter framework에서
setState()
는 build() method를 부릅니다. 이는 UI를 새로 update 합니다. -
hot reload 결과 확인
app을 Hot reload 시켜 하트 아이콘이 토글 되는지 확인 합니다.
아래와 같이 보여질 것입니다.Android iOS
Problems?
해결되지 않는 문제가 있다면 아래 완성된 코드를 참고하여 수정 하세요.
Step 3: Navigate to a new screen
이번 스텝에서는 새로운 페이지를 만들어 favorite 지정된 단어를 출력 시켜 보겠습니다.
이번 과정에서 화면간의 route를 어떻게 하는지 배울 수 있습니다.
Flutter에선 Navigator 가 stack 형태로 app의 route를 관리 합니다.
새로운 route를 push 하여 새로운 화면으로 이동 하며, pop 하여 이전 화면으로 돌아 갈 수 있습니다.
다음으로, AppBar에 list icon()을 추가하겠습니다.
RandomWordsState
class의 build method에 추가 합니다.
사용자가 list icon을 클릭 하면 favorite 단어를 보여주는 페이지의 새로운 route가 push 됩니다.
-
list icon을 추가 하고 그에 따른 action을 build method에 추가 합니다.
아래 소스코드를 참고 하세요.class RandomWordsState extends State
{ ... @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Startup Name Generator'), actions: [ // Add 3 lines from here... IconButton(icon: Icon(Icons.list), onPressed: _pushSaved), ], // ... to here. ), body: _buildSuggestions(), ); } ... } Tip!!: 어떤 widget property는 한개의 widget만을 받습니다. 예를들어 child widget이 그렇습니다. 어떤 widget은 여러 widget을 array 형태로 받습니다. 예를들면 children widget이 그렇습니다. array 는 [] 모양으로 표시 됩니다.
-
_pushSaved()
function을RandomWordsState
class에 추가 합니다.void _pushSaved() { }
-
hot reload 하여 변경사용을 적용 합니다. list icon (
) 이 app bar에 나타납니다.
아직은 클릭해도 아무런 액션이 없습니다. _pushSaved() function이 비어 있기 때문입니다.
이제 새로운 route를 build 하고 Navigator stack에 push 해보겠습니다.
이 action을 통해 screen이 이동 될 것입니다.
새로운 페이지는 MaterialPageRoute 의 builder property 의 annonymous(익명) 함수로 구현 합니다. -
Navigator.push
를 추가합니다. 이를 호출 하면 Navigator stack에 새로운 route를 push 합니다.
MaterialPageRoute
를 추가하고builder
property를 추가 합니다. builder에는 ListTile row를 생성하는 code를 넣습니다.
divideTiles()
method 는 row간의 공간을 만듭니다.
divided
변수는 전체 row를 list 로 변환하여 갖고 있습니다.
_pushSaved()
function을 아래 소스 코드를 참고하여 작성 하세요.void _pushSaved() { Navigator.of(context).push( MaterialPageRoute
( // Add 20 lines from here... builder: (BuildContext context) { final Iterable tiles = _saved.map( (WordPair pair) { return ListTile( title: Text( pair.asPascalCase, style: _biggerFont, ), ); }, ); final List divided = ListTile .divideTiles( context: context, tiles: tiles, ) .toList(); }, ), // ... to here. ); } builder property 는 이름이 "Saved Suggestions."인 Scaffold 를 return 합니다.
Scaffold의 name은 "Saved Suggestions." 이고 body 는 ListTiles row를 포함하는 ListView로 구성됩니다.
각 row는 divider로 구분됩니다. -
divider를 추가합니다. 아래 소스 코드를 참고하세요.
void _pushSaved() { Navigator.of(context).push( MaterialPageRoute
( builder: (BuildContext context) { final Iterable tiles = _saved.map( (WordPair pair) { return ListTile( title: Text( pair.asPascalCase, style: _biggerFont, ), ); }, ); final List divided = ListTile .divideTiles( context: context, tiles: tiles, ) .toList(); return Scaffold( // Add 6 lines from here... appBar: AppBar( title: Text('Saved Suggestions'), ), body: ListView(children: divided), ); // ... to here. }, ), ); } -
hot reload 하여 변경사용을 적용 합니다.
Favorite 단어가 지정되고, icon 색상이 변경 되며,
app bar의 list icon을 클릭하여 saved suggestions page로 이동 할 수 있습니다.
back 버튼을 통해 다시 home으로 돌아 올 수 있습니다.
Navigator.pop을 구현하지 않았지만 back 버튼을 통해 home으로 이동 할 수 있습니다.
최종 결과물은 아래 이미지와 같습니다.Home Page2
Problems?
해결되지 않는 문제가 있다면 아래 완성된 코드를 참고하여 수정 하세요.
Step 4: Change the UI using Themes
이번 스텝에서는 app의 theme를 변경 해볼 것입니다.
theme 를 변경하면 전체적인 app의 분위기를 쉽게 변경 할 수 있습니다.
물론 default theme을 이용 하거나 커스텀 theme를 사용 할 수도 있습니다.
ThemeData class 를 이용 하여 theme 를 변경 할 수 있습니다.
-
color 변경
MyApp class 의 build method에 theme property를 추가 합니다.class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Startup Name Generator', theme: ThemeData( // Add the 3 lines from here... primaryColor: Colors.white, ), // ... to here. home: RandomWords(), ); } }
-
hot reload 하여 변경된 결과를 확인 하세요.
color 외에도 여러가지 변경 할 수 있습니다.Android iOS
Problems?
해결되지 않는 문제가 있다면 아래 완성된 코드를 참고하여 수정 하세요.
Step 5: Well done
수고하셨습니다.
목표로 했던 application을 완성 하였습니다.
우리는 이번 실습을 통해 아래와 같은 내용을 학습했습니다.
- Dart code 작성
- Hot reload 사용
- stateful widget 사용
- interactivity 추가
- route control
- theme 변경