작성자 : gmlwo530
리스트를 만드는 방법들을 공부해봤습니다.
flutter에는 리스트를 만들 수 있는 ListView
를 제공해줍니다. 이 위젯을 이용하여 만들어보겠습니다.
ListView는 기본적으로 방향이 vertical입니다.
ListTile은 고정 된 높이를 가지고 있는 행입니다. 텍스트와 아이콘 등을 추가 할 수 있는 속성을 가지고 있습니다.
ListView(
children: <Widget>[
ListTile(
leading: Icon(Icons.map),
title: Text('Map'),
),
ListTile(
leading: Icon(Icons.photo_album),
title: Text('Album'),
),
ListTile(
leading: Icon(Icons.phone),
title: Text('Phone'),
),
],
);
만약 수평 리스트를 만들고 싶다면 scrollDirection
속성을 사용하면 됩니다.
ListView(
// This next line does the trick.
scrollDirection: Axis.horizontal,
children: <Widget>[
Container(
width: 160.0,
color: Colors.red,
),
Container(
width: 160.0,
color: Colors.blue,
),
Container(
width: 160.0,
color: Colors.green,
),
Container(
width: 160.0,
color: Colors.yellow,
),
Container(
width: 160.0,
color: Colors.orange,
),
],
)
가끔씩 UI를 구성 할 때 Grid에 기반하여 List를 구현하고 싶을 떄도 있다. GridView
를 통해 Grid List를 구현해보자
List는 기본적으로 수직 방향을 가지고 있으므로 아래의 코드는 열이 2개가 생긴다. 만약 scrollDirection
을 바꿔주면 행이 2개가 생긴다.
List.generate()
는 n개의 widget을 생성해준다.
GridView.count(
// scrollDirection: Axis.horizontal,
crossAxisCount: 2,ㄴ
children: List.generate(100, (index) {
return Center(
child: Text(
'Item $index',
style: Theme.of(context).textTheme.headline,
),
);
}),
);
이번에는 리스트에 item마다 형태가 다른 리스트를 만들어 보겠습니다.
헤더가 있고 헤더에 각각의 item이 있는 형태를 예로 들 수 있습니다.
먼저 데이터의 형태를 정의한다.
abstract class ListItem {}
class HeadingItem implements ListItem {
final String heading;
HeadingItem(this.heading);
}
class MessageItem implements ListItem {
final String sender;
final String body;
MessageItem(this.sender, this.body);
}
이제 데이터를 만들자.
final items = List<ListItem>.generate(
1200,
(i) => i % 6 == 0
? HeadingItem("Heading $i")
: MessageItem("Sender $i", "Message body $i"),
);
List를 만들기 위해 ListView.builder() constructor를 사용한다.
builder는 오직 화면에 보여지는 item들만 호출하기 때문에 굉장히 많은(또는 무제한) 데이터를 다룰 떄 사용하기 적합하다.
note : ListView.builder by default does not support child reordering. If you are planning to change child order at a later time, consider using ListView or ListView.custom.
그리고 어떤 타입의 데이터인지 is
키워드를 사용해서 구분한다.
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
if (item is HeadingItem) {
return ListTile(
title: Text(
item.heading,
style: Theme.of(context).textTheme.headline,
),
);
} else if (item is MessageItem) {
return ListTile(
title: Text(item.sender),
subtitle: Text(item.body),
);
}
},
);
리스트의 아이템을 클릭해야하는 하는 상황이 자주 생길 것이다.
위에 예제에 추가해보았다.
onTap()
또는 onLongTouch
콜백을 사용하면 된다.
ListView(
children: <Widget>[
ListTile(
leading: Icon(Icons.map),
title: Text('Map'),
onTap: () {
print('Map');
}
),
ListTile(
leading: Icon(Icons.photo_album),
title: Text('Album'),
onTap: () {
print('Album');
}
),
ListTile(
leading: Icon(Icons.phone),
title: Text('Phone'),
onTap: () {
print('Phone');
}
),
],
);
GestureDector 위젯을 사용하자.
이 위젯을 item view에 감싸주면 된다.
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return GestureDetector(
onTap: () {
print('click!');
},
child: Container(
color: Colors.yellow,
child: Text('Box'),
),
)
},
);
Reference