본문 바로가기
스파르타 코딩 클럽 내일배움캠프 6기/[Flutter 트랙] 앱개발 종합반

[Flutter 트랙] 앱개발 종합반 2-4 - ListView

by 앱 창업 부트캠프 2025. 3. 4.

Flutter ListView 위젯

ListView 위젯은 스크롤 가능한 리스트 형태의 UI를 구현하는 데 사용됩니다. 대표적인 사용 사례로는 카카오톡 친구 목록, 쿠팡 상품 리스트 등이 있습니다.


1. ListView 기본 개념

ListView를 사용하면 여러 개의 항목을 리스트 형태로 표시하고, 세로 또는 가로로 스크롤할 수 있습니다.

ListView 특징

  • 스크롤 가능한 리스트 형태 UI 제공
  • 가로/세로 방향 조정 가능
  • 컨트롤러를 이용하여 특정 위치로 이동 가능
  • 캐싱을 활용하여 성능 최적화 가능

ListView 기본 예제


import 'package:flutter/material.dart';

void main() {
    runApp(MaterialApp(home: ListViewExample()));
}

class ListViewExample extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return Scaffold(
            body: ListView(
                children: List.generate(10, (index) {
                    return ListTile(
                        title: Text("아이템 ${index + 1}"),
                        leading: Icon(Icons.star),
                    );
                }),
            ),
        );
    }
}

➡️ 리스트가 자동으로 스크롤 가능하며, ListTile을 사용해 아이콘과 텍스트를 포함한 리스트를 생성할 수 있습니다.


2. ListView 스크롤 방향 변경

기본적으로 ListView세로 방향으로 스크롤됩니다. 하지만 가로 스크롤로 변경할 수도 있습니다.

가로 스크롤 ListView 예제


ListView(
    scrollDirection: Axis.horizontal,  // 기본값은 Axis.vertical
    children: List.generate(5, (index) {
        return Container(
            width: 100,
            margin: EdgeInsets.all(8),
            color: Colors.blue,
            child: Center(child: Text("아이템 ${index + 1}")),
        );
    }),
),

➡️ scrollDirection: Axis.horizontal 을 설정하면 좌우 스크롤이 가능해집니다.


3. ListView 역순 정렬 (Reverse)

채팅 앱처럼 최근 메시지가 아래에서 위로 정렬되는 UI를 만들고 싶다면, reverse: true 옵션을 사용하면 됩니다.

역순 정렬 ListView 예제


ListView(
    reverse: true,  // 역순 정렬
    children: List.generate(10, (index) {
        return ListTile(
            title: Text("메시지 ${index + 1}"),
        );
    }),
),

➡️ reverse: true 설정 시, 최근 데이터가 아래에서 위로 정렬됩니다.


4. ListView 컨트롤러 사용 (특정 위치로 이동)

버튼을 클릭하면 리스트의 특정 위치로 이동할 수 있습니다.

특정 위치로 이동하는 예제


class ListViewWithController extends StatefulWidget {
    @override
    _ListViewWithControllerState createState() => _ListViewWithControllerState();
}

class _ListViewWithControllerState extends State<ListViewWithController> {
    final ScrollController _controller = ScrollController();  // 스크롤 컨트롤러 생성

    void scrollToPosition() {
        _controller.jumpTo(300);  // 특정 위치(픽셀 단위)로 이동
    }

    @override
    Widget build(BuildContext context) {
        return Scaffold(
            body: Column(
                children: [
                    ElevatedButton(
                        onPressed: scrollToPosition,
                        child: Text("3번째 아이템으로 이동"),
                    ),
                    Expanded(
                        child: ListView.builder(
                            controller: _controller,  // 컨트롤러 등록
                            itemCount: 20,
                            itemBuilder: (context, index) {
                                return ListTile(
                                    title: Text("아이템 ${index + 1}"),
                                );
                            },
                        ),
                    ),
                ],
            ),
        );
    }
}

➡️ 버튼을 클릭하면 300픽셀 위치로 스크롤됩니다.


5. ListView 스크롤 물리 효과 (Physics)

ListView의 스크롤 효과를 조정할 수 있습니다.

Physics 옵션 예제


ListView(
    physics: BouncingScrollPhysics(),  // iOS 스타일의 바운싱 효과 적용
    children: List.generate(10, (index) {
        return ListTile(
            title: Text("아이템 ${index + 1}"),
        );
    }),
),

➡️ BouncingScrollPhysics() 설정 시, iOS처럼 리스트 끝에서 탄성 효과(Bounce)가 나타납니다.

스크롤 비활성화


ListView(
    physics: NeverScrollableScrollPhysics(),  // 스크롤 비활성화
    children: List.generate(10, (index) {
        return ListTile(
            title: Text("아이템 ${index + 1}"),
        );
    }),
),

➡️ NeverScrollableScrollPhysics()를 설정하면 사용자가 리스트를 스크롤할 수 없게 됩니다.


6. ListView 패딩 (Padding)

리스트의 내부 여백을 조정할 수 있습니다.

Padding 옵션 예제


ListView(
    padding: EdgeInsets.all(20),  // 상하좌우 여백 20
    children: List.generate(10, (index) {
        return ListTile(
            title: Text("아이템 ${index + 1}"),
        );
    }),
),

➡️ EdgeInsets.all(20) 설정 시, 리스트 내부의 모든 방향에 20픽셀 여백이 추가됩니다.


7. ListView 캐싱 최적화 (CacheExtent)

ListView의 성능을 최적화하기 위해, 미리 캐싱할 범위를 설정할 수 있습니다.

CacheExtent 옵션 예제


ListView.builder(
    cacheExtent: 500,  // 500px 범위까지 미리 로드
    itemCount: 50,
    itemBuilder: (context, index) {
        return ListTile(
            title: Text("아이템 ${index + 1}"),
        );
    },
),

➡️ cacheExtent: 500 설정 시, 리스트의 500픽셀 범위까지 미리 로드됩니다.


8. 결론

  • ListView스크롤 가능한 리스트 UI를 쉽게 구현
  • 세로/가로 방향, 역순 정렬, 패딩, 캐싱 등 다양한 옵션 제공
  • ScrollController를 활용하면 특정 위치로 이동 가능
  • Physics 옵션을 사용하여 스크롤 효과를 조정 가능

다음 강의에서는 GridView 위젯을 살펴보겠습니다! 🚀