Flutter

[Flutter] 플러터의 스크롤 위젯을 알아보자

연화 2025. 1. 8. 17:38

 

Flutter는 다양한 레이아웃과 스크롤 위젯을 제공하며,
그 중에서도 ListView, PageView, GridView는 가장 많이 사용되는 위젯입니다.
이 글에서는 이 세 가지 위젯의 사용법, 주요 속성, 그리고 실습 예제를 함께 살펴보겠습니다.

 

1. ListView 위젯

ListView는 스크롤 가능한 리스트를 만드는 데 사용되며, Flutter에서 가장 일반적인 스크롤 위젯입니다.

ListView 사용 방식

  1. children 전달 방식: 적은 양의 데이터를 다룰 때 사용.
  2. ListView.builder: 동적인 리스트를 생성할 때 사용.
  3. ListView.separated: 동적 리스트와 구분선이 필요한 경우 사용.

주요 속성

  • reverse: true로 설정하면 리스트가 아래에서 위로 표시됩니다.
  • padding: 리스트 아이템 간격을 EdgeInsets로 지정합니다.
  • itemCount: 리스트 아이템 개수를 정의 (builder/separated 사용 시).
  • itemBuilder: 각 리스트 아이템을 정의 (builder/separated 사용 시).
  • physics: 스크롤 방식 설정.

 

ListView 실습하기
import 'package:flutter/material.dart';
import 'package:flutter_list_grid_page/main.dart';

//ListView 와 ListTile 위젯을 살펴보자
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: ListView(
          children: [
            ListTile(
              leading: CircleAvatar(
                backgroundColor: Colors.amber,
                child: Text('1'),
              ),
              title: Text('item1'),
              subtitle: Text('item1 sub description'),
              trailing: IconButton(
                onPressed: () {
                  print('item1 클릭했어요');
                },
                icon: Icon(Icons.more_horiz),
              ),
            ),
            ListTile(
              leading: CircleAvatar(
                backgroundColor: Colors.amber,
                child: Text('2'),
              ),
              title: Text('item2'),
              subtitle: Text('item2 sub description'),
              trailing: IconButton(
                onPressed: () {
                  print('item2 클릭했어요');
                },
                icon: Icon(Icons.more_horiz),
              ),
            ),
            ListTile(
              leading: CircleAvatar(
                backgroundColor: Colors.amber,
                child: Text('3'),
              ),
              title: Text('item3'),
              subtitle: Text('item3 sub description'),
              trailing: IconButton(
                onPressed: () {
                  print('item3 클릭했어요');
                },
                icon: Icon(Icons.more_horiz),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
ListView.builder 실습하기
import 'package:flutter/material.dart';
import 'package:flutter_list_grid_page/main.dart';

//ListView 와 ListTile 위젯을 살펴보자
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: ListView.builder(
          itemCount: 20,
          itemBuilder: (context, index) {
            return ListTile(
              leading: CircleAvatar(
                backgroundColor: Colors.amber,
                child: Text('${index + 1}'),
              ),
              title: Text('item ${index + 1}'),
              subtitle: Text('Item sub ${index + 1}'),
              trailing: IconButton(
                  onPressed: () {},
                  icon: Icon(
                    Icons.add,
                    color: Colors.grey,
                  )),
            );
          },
        ),
      ),
    );
  }
}
ListView.separated 실습하기
import 'package:flutter/material.dart';
import 'package:flutter_list_grid_page/main.dart';

//ListView 와 ListTile 위젯을 살펴보자
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: ListView.separated(
            itemBuilder: (context, index) {
              return ListTile(
                leading: CircleAvatar(
                  backgroundColor: Colors.amber,
                  child: Text('${index + 1}'),
                ),
                title: Text('item ${index + 1}'),
                subtitle: Text('Item sub ${index + 1}'),
                trailing: IconButton(
                    onPressed: () {},
                    icon: Icon(
                      Icons.add,
                      color: Colors.grey,
                    )),
              );
            },
            separatorBuilder: (context, index) {
              return Divider(
                indent: 10.0,
                endIndent: 10.0,
                thickness: 1.0,
                height: 20.0,
              );
            },
            itemCount: 20),
      ),
    );
  }
}

 

2. GridView 위젯

GridView는 한 줄에 여러 아이템을 배치하는 그리드 레이아웃을 제공합니다. 주로 그리드 형태의 아이템 목록을 만들 때 사용됩니다.

주요 속성

  • gridDelegate: 그리드 형태를 설정.
    • crossAxisCount: 한 줄에 표시할 아이템 개수.
    • crossAxisSpacing: 열 간격.
    • mainAxisSpacing: 행 간격.
  • itemCount: 아이템 개수.
  • itemBuilder: 각 그리드 아이템 정의.
GridView 실습하기
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: GridView.builder(
          scrollDirection: Axis.vertical,
          itemCount: 27,
          //그리드의 열 개수를 고정하는 속성입니다
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3,
            crossAxisSpacing: 5,
            mainAxisSpacing: 5,
          ),
          itemBuilder: (context, index) {
            return Container(
              color: Colors.blueAccent,
              child: Center(child: Text('${index}')),
            );
          },
        ),
      ),
    );
  }
}

3. PageView 위젯

PageView는 스와이프 이벤트를 통해 페이지 전환을 구현하는 데 사용됩니다. 가로 또는 세로 방향으로 스크롤할 수 있는 슬라이더 형태를 제공합니다.

PageController 속성

  • initialPage: 처음 표시할 페이지.
  • viewportFraction: 페이지가 화면에 차지하는 비율 (0.7로 설정하면 양옆 페이지가 살짝 보임).
PageView 실습하기
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SafeArea(
        child: Scaffold(
          appBar: AppBar(
            title: Text('pageview'),
          ),
          body: PageView(
            controller: PageController(
              initialPage: 2,
              viewportFraction: 0.9,
            ),
            children: [
              Container(
                margin: EdgeInsets.all(0.0),
                color: Colors.red,
              ),
              Container(
                margin: EdgeInsets.all(0.0),
                color: Colors.blue,
              ),
              Container(
                margin: EdgeInsets.all(0.0),
                color: Colors.green,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

 

Flutter의 ListView, GridView, PageView는 다양한 UI를 손쉽게 구현할 수 있는 강력한 도구입니다.
각 위젯의 특징과 사용법을 이해하고, 상황에 맞게 선택하여 활용하면 더욱 효과적인 앱을 개발할 수 있습니다.

 

💡 플러터의 기본 위젯도 알고 싶어요

 

[Flutter] 플러터의 Basic Widget 살펴보기

Flutter는 다양한 위젯을 제공하며, 이를 이해하고 활용하는 것이 효율적인 UI 개발의 핵심입니다. 이번 포스팅에서는 Flutter에서 자주 사용되는 Basic Widget에 대해 살펴보고, 예제 코드와 함께 실제

dev-yeonwha.tistory.com