Flutter - ListView inside ListView with shrinkwrap
ListView안에 ListView를 넣어야되는 상황이 생길때가 있습니다
그래서 이 부분을 간단하게 처리하는 방법중 하나를 소개해드리고자 합니다
먼저 필요한 부분을을 조금 더 이해하기 쉽게 설명하기 위해
가장 유사하고 간단한 예를 먼저 들어드리겠습니다
이전에 단톡방에 "horizontal Listview에 ListTile을 넣었는데 에러가 난다"
라는 질문에 대한 답변을 드린적이 있는데 이 부분부터 간단히 짚고 넘어가겠습니다
"ListTile은 width를 정해주지 않아도 자동으로 끝에서 끝으로 그려주죠 Expanded처럼요
그래서 ListView를 가로로했을때 ListTile을 특정 width로 안 감싸주면 infinite width가 돼서
에러가 발생하게 됩니다" 제가 이렇게 답변을 드렸던 기억이 있습니다
여기서 ListView안에 column이 들어가고 ListView가 또 들어가게 된다면
ListView자체가 크기를 확보할 수 있는만큼 확보를 하기 때문에 unbounded height이 됩니다
위 horizontal과 약간 다르지만 같은 이치죠
그래서 여기서 shrinkwrap을 사용하게 됩니다
class NestedListView extends StatelessWidget {
final String title;
final List<int> _header = List.generate(9, (index) => index + 1);
final List<int> _body = List.generate(9, (index) => index + 1);
NestedListView(this.title);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(title)),
body: ListView.builder(
itemCount: _header.length,
itemBuilder: (_, index) {
int dan = _header[index];
return Column(
children: [
Chip(label: Text('$dan 단')),
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: _body.length,
itemBuilder: (_, index) {
int num = _body[index];
return Card(
child: ListTile(
title: Text('$dan x $num = ${dan * num}')));
})
],
);
}),
);
}
}
간단한 구구단 출력 예제인데
shrinkwrap true를 하게되면 child크기만큼만 할당하게 돼고 그 결과 출력이 잘 됩니다
근데 여기서 만약 physics를 그대로 둔다면 위 ListView와 아래 ListVIew의 scroll이 겹치게 되어
원하는 작동을 안하게 될 경우가 생깁니다
그래서 아래에 있는 ListView에 NeverScrollableScrollPhysics를 이용해서
아래 ListVIew의 스크롤을 금지하면 위 ListView의 scroll만으로 작동을 하기 때문에 잘 작동이 됩니다
혹은 위 ListView도 shrinkwrap true, NeverScrollableScrollPhysics를 사용하고
SingleChildScrollView를 사용해도 무방합니다
조금 더 편한쪽으로 사용하시면 될거같습니다