2020. 11. 25. 07:36ㆍIT
리스트에 아이콘 추가하기
이번에는 지금까지 만든 리스트 맨 오른쪽에 하트 모양의 아이콘을 추가할 것입니다. 그리고 리스트를 클릭해 선택을 하면 아이콘 모양을 바꿔보도록 하겠습니다. 선택된 리스트를 클릭하면 아이콘을 원래대로 복귀시킵니다.
그 뿐만 아니라 선택이 된 리스트들만 따로 보여주는 페이지를 만들어 보도록 하겠습니다.
앞의 그림에서 본 바와 같이 우리는 리스트에 하트 아이콘(Favorite)을 달고 선택이 되면 빨간색 하트로 변경을 하고 저장된 리스트를 Saved Suggestion라는 별도의 창에 보이도록 만들어 보겠습니다.
_RandomWordsState 클래스에 에 선택이 된 항목들을 저장하기 위한 _saved를 선언해 줍니다.
class _RandomWordsState extends State<RandomWords> {
final List<WordPair> _suggestions = <WordPair>[];
final _saved = Set<WordPair>();
final TextStyle _biggerFont = const TextStyle(fontSize: 18);
그리고 _buildRow 함수에 alreadySaved 라는 변수를 선언을 다음과 같이 해 주는데 이 변수의 용도는 이미 선택이 된 WordPair를 빨간색 하트 아이콘으로 칠해주고, 선택이 되지 않은 하트는 색칠을 하지 않는데 사용하기 위함입니다.
-
set collection data type
set은 자료를 모아 놓을 수 있는 형식이며 list와 유사하나 set은 중복된 값을 가질 수 없다는 것이 list와 다른 점이라고 합니다. 여기서는 set을 통해서 사용자로 부터 선택이 된 자료들을 저장을 하기 위한 용도로 _saved가 선언이 되었습니다.
다음의 _buildRow 함수를 보시면 저장이 되어 있는 변수는 alreadySaved에 저장이 됩니다. ListTile의 Text 위젯에 텍스트를 출력하고 우측에 아이콘을 표시해야 하는데 List의 오른쪽을 Trailing이라고 합니다. Trailing에 Icon 위젯을 넣습니다. 그리고 alreadySaved가 True(참)이면 Icon을 favorite로 설정을 하고 그렇지 않으면 favorite_border로 설정을 합니다. 그리고 color도 저장되어 있는 것이라면 red로 설정을 하고 그렇지 않으면 색칠을 하지 않습니다.
Widget _buildRow(WordPair pair) {
final alreadySaved = _saved.contains(pair);
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
trailing: Icon(
// NEW from here...
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red : null,
),
);
}
실행을 해 보면 리스트에 하트까지는 나타납니다만 선택은 되지 않습니다. 아직까지 선택을 하는 함수를 구현하지 않았기 때문이죠.
-
? 연산자
이 연산자는
조건 ? 참일 때 수행 : 거짓일 때 수행
과 같이 설명을 할 수 있습니다.
-
Icon 위젯
아이콘 위젯에 대해서 알아보기 위해서는 Ctrl 버튼을 누른 상태에서 Icon을 마우스로 클릭하면 Icon class로 이동을 합니다. 다음과 같은 화면을 보실 수 있습니다.
아이콘은 첫번째 Icon과 { … } 사이에 있는 인자들을 이용해서 그릴 수 있습니다.
{ … } 사이에 있는 값들은 옵션이기 때문에 아이콘을 출력하기 위해서는 아이콘 값만 넣어줘도 됩니다. 아이콘은 이미 플러터에서 수 백개가 정의가 되어 있습니다. 아이콘은 다음의 링크를 따라가서 보시면 다양한 아이콘의 정체를 확인할 수 있습니다.
https://api.flutter.dev/flutter/material/Icons-class.html
사용자가 리스트를 선택해도 아무런 동작이 일어나지 않았습니다. 이는 우리가 리스트를 클릭했을 때 어떤 동작을 해야할지 우리 앱에게 알려주지 않았기 때문입니다. 리스트를 클릭한다고 표현을 했는데 플러터에서는 탭을 했다고 표현을 합니다. 아래의 _buildRow 함수의 ListTile 위젯을 보면 onTap이라는 것이 추가가 되어 있습니다.
Widget _buildRow(WordPair pair) {
final alreadySaved = _saved.contains(pair);
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
trailing: Icon(
// NEW from here...
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red : null,
),
onTap: () {
setState(() {
if (alreadySaved) {
_saved.remove(pair);
} else {
_saved.add(pair);
}
});
},
);
}
onTap은 사용자가 리스트를 클릭하거나 터치를 했을 때를 의미합니다. onTap이 발생을 했을 때 setState() 함수를 호출하여 플러터에게 내 상태가 바뀌었으니 다시 그리라고 알려 줍니다. 그 상태는 setState() 함수 내의 if문에서 설정이 됩니다.
alreadySaved 즉, 이미 선택이 되어 있는데 또 사용자가 눌렀다면 _saved 즉, 사용자가 클릭을 해서 이미 하트가 빨간색으로 칠해져 있었다면 _saved에서 remove 함수를 이용해서 선택한 pair를 삭제 합니다.
만일 선택이 되지 않아 색칠되지 않은 하트를 가진 리스트는 _saved에 선택된 pair를 저장합니다.
onTap을 하면 setState()를 통해 state가 변한 것을 플러터로 보내고 플러터는 ListTile의 trailing에 정의된 대로 _saved 여부에 따라서 리스트를 다시 그려줍니다. 다시 그리기 위해서는 build 함수가 호출이 될 것입니다.
'IT' 카테고리의 다른 글
[Flutter #15] gitHub (0) | 2020.11.25 |
---|---|
[Flutter #14] 새로운 페이지 추가 (0) | 2020.11.25 |
[Flutter #12] 리스트 뷰 (0) | 2020.11.25 |
[Flutter #11] Stateful 위젯 (0) | 2020.11.25 |
[Flutter #10] 외부 패키지 이용하기 (1) | 2020.11.24 |