본문 바로가기
flutter

플러터 - ListView

by 들풀민들레 2023. 3. 13.
본 글은 [Do it! 깡샘의 플러터&다트 프로그래밍] 의 내용을 발췌한 것입니다.

 

 

책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.

 

리스트 뷰는 크게 2가지 목적으로 사용합니다. 여러 위젯을 세로나 가로로 나열하면서 화면을 벗어날 때 스크롤을 지원하고자 사용하고, 일반 목록 화면처럼 항목을 나열하고자 사용합니다. 물론 목록 화면도 항목을 여러 개 나열하여 화면을 벗어날 때 자동 스크롤을 지원하므로 리스트 뷰의 목적은 하나라고 봐도 됩니다. 단지 위젯을 항목처럼 나열할 것인지 차이만 있습니다.

 

화면 스크롤 지원하기


다음은 위젯 여러 개가 나열되다가 화면을 벗어나서 스크롤이 필요한 상황입니다.

Column(
	children: [
		Container(height: 300,color: Colors.red,),
		Container(height: 300,color: Colors.green,),
		Container(height: 300,color: Colors.blue,),
	],
)
 

 

책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.

 

 

 

Column에 위젯 3개를 추가했는데 세로로 화면을 벗어나는 상황입니다. 플러터 앱은 위젯이 화면을 벗어날 때 스크롤을 지원하지 않으면 노랑과 검정 패턴의 경고 영역으로 보여 줍니다.
똑같은 위젯을 스크롤이 지원되는 ListView로 바꾸면 스크롤 경고 영역이 사라집니다.

ListView(
	children: [
		Container(height: 300,color: Colors.red,),
		Container(height: 300,color: Colors.green,),
		Container(height: 300,color: Colors.blue,),
	],
)

리스트 뷰는 위젯을 세로로 나열할 때 주로 사용하지만 원한다면 가로로 나열할 수도 있습니다. scrollDirection 속성을 Axis.horizontal로 설정하면 됩니다.

ListView(
	scrollDirection: Axis.horizontal,
	children: [
		Container(width: 150,color: Colors.red,),
		Container(width: 150,color: Colors.green,),
		Container(width: 150,color: Colors.blue,),
	],
)

목록 구성하기


리스트 뷰를 이용할 때 생성자는 ListView()를 이용해도 되고 ListView.builder()를 이용해도 됩니다. 둘 다 똑같은 화면을 만들 수 있습니다. 그런데 ListView() 생성자를 이용하면 children 속성에 리스트 뷰에 보일 항목을 나열해야 하는데, 항목이 많아지면 문제가 될 수 있습니다.
예를 들어 항목이 100개이고 처음 리스트 뷰가 화면에 나올 때 4개만 보인다면 아직 보이지 않는 96개 항목까지 모두 준비해야 하므로 비효율적입니다. 항목이 많더라도 초기 화면에 보일 항목만 구성하고 나머지는 사용자가 스크롤할 때 준비해서 나오게 하면 효율적입니다. ListView.builder() 생성자는 바로 이런 기능을 제공합니다.


항목을 스크롤에 따라 불러오기 — ListView.builder()
ListView.builder() 생성자에는 itemCount와 itemBuilder라는 속성을 설정합니다. itemCount는 리스트 뷰에 출력할 항목 수이며, itemBuilder는 항목을 구성하는 위젯을 만들어 주는 함수입니다. 이 함수에서 반환한 위젯이 각 항목에 출력됩니다.
여기서 중요한 점은 itemCount에 100을 설정하더라도 itemBuilder에 지정한 항목 위젯을 만드는 함수가 처음부터 100번 호출되지는 않는다는 것입니다. 처음 화면에 나올 개수만큼만 호출되며 이후 스크롤이 발생하여 항목이 더 필요해지면 그때 다시 호출됩니다.

List<String> citys = [
	'서울시','인천시','부산시','대구시','대전시','광주시','울산시','세종시'
];
@override
Widget build(BuildContext context) {
	return ListView.builder(
		itemCount: citys.length,
		itemBuilder: (context, index){
			return Container(
				padding: EdgeInsets.only(left: 10, top: 10),
				height: 100,
				child: Text(citys[index]),
			);
		},
	);
}

항목 구분자 설정하기 — ListView.seperated()
ListView.seperated() 생성자는 itemCount와 itemBuilder를 이용해 항목의 개수와 항목을 구성하는 위젯을 지정한다는 면에서 ListView.builder()와 같습니다. 그런데 ListView.builder()는 항목의 구분자를 나타내는 별도의 속성을 제공하지 않습니다. 물론 item Builder에 지정하는 함수에서 구분자 역할을 하는 위젯을 따로 준비해도 되지만, ListView.seperated() 생성자를 이용하면 항목 구분자를 조금 더 쉽게 지정할 수 있습니다.
ListView.seperated() 생성자의 seperatorBuilder 속성에 지정하는 함수에서 구분자로 사용할 위젯을 준비해 반환하면 자동으로 반환한 위젯이 구분자로 출력됩니다. 구분자 위젯으로는 다음처럼 Divider를 주로 사용합니다. Divider 위젯은 가로선을 출력하는 위젯이며 선의 두께, 색상 등을 지정할 수 있습니다.

ListView.separated(
	itemCount: citys.length,
	itemBuilder: (context, index){
		return Container(
			padding: EdgeInsets.only(left: 10, top: 10),
			height: 100,
			child: Text(citys[index]),
		);
	},
	separatorBuilder: (context, index){
		return Divider(height: 2, color: Colors.black,);
	},
)

항목 구성하기 — ListTile


ListTile은 항목을 구성하는 위젯입니다. 리스트 뷰에 나오는 항목은 ListTile을 사용하지 않고도 다양한 위젯으로 구성할 수 있습니다. 그러나 대부분의 리스트 뷰는 문자열을 하나 출력하거나 두 개를 위아래로 배치합니다. 또한 문자열 왼쪽에는 이미지, 오른쪽에는 아이콘 등의 콘텐츠가 나오게 합니다. 항목을 이런 스타일로 구성할 때 ListTile 위젯을 사용하면 편리합니다.

ListTile 생성자에는 title, subtitle, leading, trailing 등의 속성이 있습니다. 이 속성에 원하는 위젯을 대입하면 항목을 다음 그림처럼 구성할 수 있습니다.

ListTile 생성자에 모든 속성을 설정하지 않고 필요한 것만 설정해도 됩니다.

ListView.separated(
	itemCount: users.length,
	itemBuilder: (context, index){
		return ListTile(
			leading: CircleAvatar(
				radius: 25,
				backgroundImage: AssetImage('images/big.jpeg'),
			),
			title: Text(users[index].name),
			subtitle: Text(users[index].phone),
			trailing: Icon(Icons.more_vert),
			onTap: (){
				print(users[index].name);
			},
		);
	},
	separatorBuilder: (context, index){
		return Divider(height: 2, color: Colors.black,);
	},
)

 

 

 

책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.

 

 

 

'flutter' 카테고리의 다른 글

플러터 - Navigation  (0) 2023.03.13
플러터 - Scaffold  (0) 2023.03.13
플러터 - TextField  (0) 2023.03.13
플러터 - Row, Column, Stack, Alignment, IndexedStack  (0) 2023.03.13
플러터 - Text Widget  (0) 2023.03.13