Layout : ListView

Clean Code Big Poo·2022년 5월 4일
0

Flutter

목록 보기
8/38
post-thumbnail

document

list view api

ListView란

  • ListView는 자주 사용할 뿐 아니라 효과적인 플러터 앱을 구현하는데 필요한 패턴과 개념을 포함한다.
  • ListView는 스크롤을 지원한다.
  • 자식의 수를 알 수 없을 때 ListView를 사용한다.
    (ex: todolist 앱에서 ListView로 목록을 표시하면 할일 항목이 하나도 없거나 많이 존재할 수 있다.)
  • ListView는 스크롤할 수 있는 Column이나 Row다.

간단한 ListView

Expanded( // --- (1)
  child: ListView(
  	padding : const EdgeInsets.all(8),
    children :<Widget>[
    	Container(height : 50 , color:Colors.amber[10]),
        Container(height : 50 , color:Colors.amber[20]),
        Container(height : 50 , color:Colors.amber[30]),
    ],//[]
  ),//ListView
)
  1. Expanded가 없으면 에러가 생긴다. ListView는 부모 위젯의 높이에 따라 높이를 맞추게 되는 데 자식 내용이 적더라도 ListView는 자신이 사용할 수 있는 최대 공간을 사용하게 된다. Column의 높이는 무한이기 때문에 ListView의 높이도 따라 무한이 된다.(에러!)
    Expanded로 감싸거나 ListView 내부에 shrinkwrap:true을 설정하면 되지만... expanded를 추천한다.
    shrinkwrap:true(자식 크기만큼 확장하라고 지시)는 높이를 미리 정하기 때문에 오버플러우가 발생할 수 있기 때문이다.

ListView.builder

Expanded( 
  child: ListView.builder(
    shrinkWrap: true, 
    itemCount: allAddedCities.length, // --- (1)
    itemBuilder: (BuildContext context, int index) { // --- (2)
      final city = allAddedCities[index];
      return Dismissible(
        onDismissed: (DismissDirection dir) => _handleDismiss(dir, city),
        confirmDismiss: (DismissDirection dir) async => 
																									dir == DismissDirection.endToStart,
        background: Container(
          child: Icon(Icons.delete_forever),
          decoration: BoxDecoration(color: Colors.red[700]),
        ),
        key: ValueKey(city),
        child: CheckboxListTile( // --- (3)
          value: city.active,
          title: Text(city.name),
          onChanged: (bool b) => _handleCityActiveChange(b, city), // --- (4)
        ),
      );
    },
  ),
)

플러터 전체에서 빌더 패턴은 자주 볼 수 있는데, 필요한 위젯을 만들 때 사용한다.
ListView.builder 생성자는 itemBuilder 프로퍼티로 콜백을 받으며 이 콜백을 통해 위젯을 반환한다. 특히 리스트에 표시해야 할 항목의 수가 아주 많거나 무한대라면 빌더 덕분에 효과적으로 화면에 항목을 그릴 수 있다. (플러터는 화면에 보이는 항목만 그린다.)

  1. 빌더는 자신이 만들 항목의 개수를 알아야 한다.
  2. BuilderContext와 인덱스를 인수로 받는 콜백으로 플러터에서 자주 사용하는 빌더 함수이다.
  3. 플러터에서 제공하는 편리한 위젯으로 체크 박스를 표시한다.
  4. 체크 박스를 제어한다. 항목을 체크하면 전달한 함수가 호출된다.

ListView.separated

Expanded( 
  child: ListView.separated(
    itemCount: allAddedCities.length,
    itemBuilder: (BuildContext context, int index) { 
      final city = allAddedCities[index];
      return Dismissible(
        onDismissed: (DismissDirection dir) => _handleDismiss(dir, city),
        confirmDismiss: (DismissDirection dir) async => 
																									dir == DismissDirection.endToStart,
        background: Container(
          child: Icon(Icons.delete_forever),
          decoration: BoxDecoration(color: Colors.red[700]),
        ),
        key: ValueKey(city),
        child: CheckboxListTile(
          value: city.active,
          title: Text(city.name),
          onChanged: (bool b) => _handleCityActiveChange(b, city),
        ),
      );
    },
   separatorBuilder :(BuildContext context, int index) => const Divider(
      height : 10.0
      color : Colors.blue,
   ),
  ),
)

ListView.separated는 ListView.builder와 비슷하지만 두 가지 빌더 메서드를 받는다. 한 가지는 리스트 항목을 만들 때 사용(itemBuilder)하고 나머지 한 가지는 리스트 항목 간의 분리자(separatorBuilder)를 만드는 데 사용한다.

ListView.custom

ListView.custom을 이용하면 커스텀 자식으로 리스트 뷰를 만든다. 빌더처럼 간단하지 않은데, 리스트 뷰의 항목을 각자 다른 항목으로 만들어야 한다고 할 때 사용하며 자식을 어떻게 그려야 할지 제어할 수 있다.

0개의 댓글