2020. 11. 25. 07:35ㆍIT
리스트 뷰
지금까지 StatelessWidget을 사용해서 MyApp을 만들었고 그 안에 StatefulWidget을 이용해서 Text 위젯에 무작위 단어가 출력되는 코드를 만들었습니다. 이 코드를 이용해서 무작위 단어들을 리스트에 넣는 것을 구현해 보도록 하겠습니다.
만들었던 _RandomWordsState 클래스 내에 단어가 들어갈 변수를 만들어 줍니다. 그리고 폰트가 작아 잘 보이지 않아 폰트를 크게 만들기 위해서 폰트 스타일을 저장을 할 변수도 함께 클래스 맨 위에 선언을 해 줍니다.
class _RandomWordsState extends State<RandomWords> {
final List<WordPair> _suggestions = <WordPair>[];
final TextStyle _biggerFont = const TextStyle(fontSize: 18);
@override
Widget build(BuildContext context) {
-
final 변수
일반적으로 final이나 const로 변수를 정해 주고 값을 넣어주면 그 값은 변경을 할 수 없습니다. 이 원칙을 따르기 때문에 앞의 _suggestions와 _biggerFont의 값은 이후의 코드에서 변경을 할 수가 없습니다.
단, _suggestions는 <WordPair>를 갖는 배열입니다. 배열에 대해서는 final로 정의를 해 줘도 예외적으로 배열 안의 값들을 변경할 수 있습니다.
다음은 _RandomWordsState 클래스 안에 ListView에 값들을 채워 넣을 _buildSuggestions라는 함수를 만들겠습니다.
Widget _buildSuggestions() {
return ListView.builder(
padding: const EdgeInsets.all(16),
itemBuilder: (BuildContext _context, int i) {
if (i.isOdd) {
return Divider();
}
final int index = i ~/ 2;
if (index >= _suggestions.length) {
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
});
}
ListView 클래스는 itemBuilder라는 속성을 이용해서 리스트에 값들을 채워 넣습니다. 그리고 여기에서는 i라는 변수가 사용이 되는데 이는 itemBuilder가 호출이 될 때마다 1씩 증가를 하며 0부터 시작합니다.
ListView에서 주의를 해야 할 것은 각 행마다 값들을 넣을 수 있는 것이 아니고 중간에 구분자(Divider)가 들어 있습니다.
/*1*/ itemBuilder는 ListView가 그려질 때 자동으로 호출이 됩니다
/*2*/ 0부터 i는 증가하는데 매번 호출 될 때마다 1씩 증가를 한다고 했습니다. 여기서는 홀수이면 Divider를 반환합니다.
/*3*/ ~/2는 2로 나누었을 때의 몫을 계산합니다. 즉 i가 0, 1, 2, 3, 4, 5의 순서로 계속 호출이 될 때마다 index는 0, 0, 1, 1, 2, 2의 값을 갖게 됩니다. 다만 /*2*/에서 홀수일 경우 반환(return)이 되므로 이 코드까지는 오지 않습니다. 따라서 i는 0, 2, 4와 같이 짝수만 이 코드에 도달하게 되고 index 값은 0, 1, 2와 같이 1씩 증가하게 됩니다.
/*4*/ 여기에서는 _suggestions가 끝에 도달했다면, 10개의 추가 공간을 _suggestions에 추가를 합니다.
마지막 return 라인에서는 생성된 WordPair가 들어있는 _suggestions를 인덱스와 함께 반환을 합니다.
이번에는 _RandomWordsState 클래스 내에 _buildRow라는 함수를 만듭니다.
ListTile에 asPascalCase의 문자와 앞서서 선언해 준 _biggerFont를 사용하여 문자의 스타일을 지정해 줍니다.
Widget _buildRow(WordPair pair) {
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
);
}
이번엔 _RandomWordsState 클래스 안의 build 클래스를 다음과 같이 변경을 해 줍니다. Stateful 위젯의 build 함수이므로 상태가 바뀔때마다 호출됩니다. 따라서 그때마다 _buildSggestions 함수를 호출을 하게 됩니다. 기존에 MyApp에 있는 Scaffold가 이쪽으로 옮겨왔다고 보시면 되겠습니다.
따라서 MyApp의 build 함수내의 MaterialApp의 home 속성에서 RadomWord를 호출해 주고 기존의 코드를 삭제합니다.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// final wordPair = WordPair.random();
return MaterialApp(
title: "환영합니다",
home: RandomWords(),
);
}
}
실행을 해 보시면 다음과 같은 결과를 얻을 수 있어야 합니다.
단 ListView에 보이는 WordPair들은 무작위로 생성된 것이므로 당연히 다르게 보일 것입니다.
최종 코드
지금까지 작성한 코드는 다음과 같습니다.
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// final wordPair = WordPair.random();
return MaterialApp(
title: "환영합니다",
home: RandomWords(),
);
}
}
class RandomWords extends StatefulWidget {
@override
_RandomWordsState createState() => _RandomWordsState();
}
class _RandomWordsState extends State<RandomWords> {
final List<WordPair> _suggestions = <WordPair>[];
final TextStyle _biggerFont = const TextStyle(fontSize: 18);
@override
Widget build(BuildContext context) {
//final wordPair = WordPair.random();
//return Text(wordPair.asPascalCase);
return Scaffold(
appBar: AppBar(
title: Text('Startup Name Generator'),
),
body: _buildSuggestions(),
);
}
Widget _buildSuggestions() {
return ListView.builder(
padding: const EdgeInsets.all(16),
itemBuilder: (BuildContext _context, int i) {
if (i.isOdd) {
return Divider();
}
final int index = i ~/ 2;
if (index >= _suggestions.length) {
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
});
}
Widget _buildRow(WordPair pair) {
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
);
}
}
.
'IT' 카테고리의 다른 글
[Flutter #14] 새로운 페이지 추가 (0) | 2020.11.25 |
---|---|
[Flutter #13] 리스트에 아이콘 추가하기 (0) | 2020.11.25 |
[Flutter #11] Stateful 위젯 (0) | 2020.11.25 |
[Flutter #10] 외부 패키지 이용하기 (1) | 2020.11.24 |
[Flutter #9] 프로젝트 생성 (0) | 2020.11.24 |