Never give up

Flutter - ListView inside ListView with shrinkwrap 본문

Flutter

Flutter - ListView inside ListView with shrinkwrap

대기만성 개발자 2021. 3. 28. 00:55
반응형

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를 사용해도 무방합니다

 

조금 더 편한쪽으로 사용하시면 될거같습니다

반응형
Comments