Framework/Flutter

[Flutter] ListView 'hasSize' 에러

서리★ 2024. 12. 13. 13:26

1. 문제: 'hasSize' 에러

 ListView.builder를 사용 중에 'hasSize' 에러가 발생하였다.

 


 

2. 원인 분석: 부모와 자식 위젯 간의 레이아웃

 일반적으로 부모 위젯의 레이아웃이 완료되기 전에 자식 위젯 또는 동일한 위젯에서 크기 관련 속성을 접근하려 할 때 발생하는 에러입니다. 우선 제가 사용한 코드를 통해 알아보겠습니다.

 

Column(
  children: [
    ListView.builder(
      itemCount: teams.length,
      itemBuilder: (context, index) {
        final team = teams[index];
        return ListTile(
          leading: Text(team.code),
          title: Text(team.name),
        );
      },
    ),
  ],
)

 

 주어진 코드에서는 Column 부모 위젯이 ListView.builder 자식 위젯을 감싸고 있습니다.
Column을 제거하고 ListView.builder만 사용하는 경우에는 에러가 발생하지 않습니다.
즉, 문제는 Column이 ListView.builder와의 특성을 고려하지 못했기 때문입니다.

 

📍 Column과 ListView.builder의 특성
Column: 기본적으로 자식 위젯에게 무한한 높이 제약을 전달
ListView.builder: 스크롤 가능한 높이를 스스로 계산 (부모로부터 고정된 높이 제약 필요)

 

부모와 자식 위젯 간의 레이아웃
부모 위젯이 ListView.builder에게 무한한 크기 제약을 전달했기 때문에,
ListView.builder가 자신의 크기를 계산하지 못해 에러가 발생하였습니다.
* 부모 위젯이 Column 뿐만 아니라 다른 상황에서도 발생할 수 있습니다.

 


 

3. 해결 방법

 

1) SizedBox

 ListView를 SizedBox로 감싸서 ListView의 크기를 명시적으로 전달합니다.

ListView의 크기를 제한할 필요가 있을 때 사용하면 됩니다.

Column(
  children: [
    SizedBox(
      height: 300,
      child: ListView.builder(
        itemCount: teams.length,
        itemBuilder: (context, index) {
          final team = teams[index];
          return ListTile(
            leading: Text(team.code),
            title: Text(team.name),
          );
        },
      ),
    ),
  ],
),

 

 

2) Expanded 또는 Flexible

 ListView를 Expanded 또는 Flexible로 감싸서 남은 영역을 채우도록 합니다.

Column(
  children: [
    Expanded(
      child: ListView.builder(
        itemCount: teams.length,
        itemBuilder: (context, index) {
          final team = teams[index];
          return ListTile(
            leading: Text(team.code),
            title: Text(team.name),
          );
        },
      ),
    ),
  ],
),