본문 바로가기
플러터(Flutter) 레이아웃 강좌

ListView와 GridView로 스크롤 가능한 레이아웃 만들기

by everythingdev 2024. 8. 27.
반응형

ListView와 GridView로 스크롤 가능한 레이아웃 만들기를 시작합니다.

  • 플러터(Flutter) 시작을 위한 다트(Dart) 강좌는 19강 단위 테스트 강좌를 끝으로 종료가 되었습니다.
  • 플러터(Flutter) 프로젝트 시작 전 디자인을 위한 레이아웃 강좌를 지속적으로 연재 중입니다.

플러터(Flutter)에서 ListView와 GridView로 스크롤 가능한 레이아웃 만들기

  • 플러터(Flutter)는 모바일 앱 개발을 위한 강력한 프레임워크입니다.
  • 사용자 인터페이스(UI)를 구축할 때 가장 중요한 요소 중 하나는 콘텐츠를 효과적으로 표시하고 스크롤할 수 있게 하는 것입니다.
  • 이를 위해 Flutter는 ListView와 GridView라는 두 가지 핵심 위젯을 제공합니다.
  • 이번 포스팅에서는 이 두 위젯을 사용하여 스크롤 가능한 레이아웃을 만드는 방법을 자세히 알아보겠습니다.

ListView: 세로 또는 가로로 스크롤 가능한 목록

  • ListView는 Flutter에서 가장 기본적이면서도 강력한 스크롤 위젯입니다.
  • 이 위젯은 항목들을 세로 또는 가로로 나열하여 표시하며, 화면을 벗어나는 항목들은 자동으로 스크롤 가능하게 만듭니다.

ListView 기본 사용법

ListView(
  children: <Widget>[
    ListTile(
      leading: Icon(Icons.map),
      title: Text('지도'),
    ),
    ListTile(
      leading: Icon(Icons.photo_album),
      title: Text('앨범'),
    ),
    ListTile(
      leading: Icon(Icons.phone),
      title: Text('전화'),
    ),
  ],
)
  • 이 코드는 세 개의 ListTile 위젯을 포함하는 기본적인 ListView를 생성합니다. 각 ListTile은 아이콘과 텍스트로 구성되어 있습니다.

ListView.builder 사용하기

  • 데이터의 양이 많거나 동적으로 변할 수 있는 경우, ListView.builder를 사용하는 것이 효율적입니다.
ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, index) {
    return ListTile(
      title: Text(items[index]),
    );
  },
)
  • ListView.builder는 필요한 항목만 렌더링하므로 메모리 사용을 최적화할 수 있습니다.

ListView 커스터마이징

  • ListView는 다양한 속성을 통해 커스터마이징이 가능합니다:
  • scrollDirection: 스크롤 방향 설정 (Axis.vertical 또는 Axis.horizontal)
  • padding: ListView 주위의 패딩 설정
  • physics: 스크롤 동작 설정 (예: BouncingScrollPhysics())

GridView: 그리드 형태로 항목 표시하기

  • GridView는 항목들을 격자 형태로 배열하여 표시합니다.
  • 이는 이미지 갤러리나 대시보드 같은 UI를 만들 때 특히 유용합니다.

GridView.count 사용하기

GridView.count(
  crossAxisCount: 2,
  children: List.generate(100, (index) {
    return Center(
      child: Text(
        'Item $index',
        style: Theme.of(context).textTheme.headline5,
      ),
    );
  }),
)
  • 이 코드는 2열의 그리드를 생성하고 100개의 항목을 표시합니다.

GridView.builder 활용

  • 대량의 데이터를 효율적으로 처리하려면 GridView.builder를 사용할 수 있습니다:
GridView.builder(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 3,
    crossAxisSpacing: 10,
    mainAxisSpacing: 10,
  ),
  itemCount: items.length,
  itemBuilder: (context, index) {
    return Container(
      color: Colors.blue,
      child: Center(
        child: Text('Item ${items[index]}'),
      ),
    );
  },
)
  • 이 방식은 필요한 항목만 렌더링하여 성능을 최적화합니다.

ListView와 GridView 성능 최적화

대량의 데이터를 다룰 때는 성능 최적화가 중요합니다. 다음은 몇 가지 최적화 기법입니다:

  • ListView.builder 및 GridView.builder 사용: 이 위젯들은 화면에 보이는 항목만 렌더링하여 메모리 사용을 줄입니다.
  • const 위젯 활용: 변경되지 않는 위젯은 const로 선언하여 불필요한 재빌드를 방지합니다.
  • 캐싱: 이미지나 복잡한 위젯의 경우, 캐싱을 통해 재사용성을 높일 수 있습니다.
  • 페이지네이션: 서버에서 데이터를 가져올 때, 한 번에 모든 데이터를 로드하지 않고 필요한 만큼만 로드하는 페이지네이션 기법을 사용합니다.

실제 프로젝트에서의 활용 예시

  • 실제 프로젝트에서 ListView와 GridView를 활용하는 몇 가지 예시를 살펴보겠습니다:

뉴스 피드 앱

ListView.builder(
  itemCount: newsItems.length,
  itemBuilder: (context, index) {
    return NewsCard(
      title: newsItems[index].title,
      summary: newsItems[index].summary,
      imageUrl: newsItems[index].imageUrl,
    );
  },
)
  • 이 코드는 뉴스 항목들을 ListView로 표시합니다. 각 뉴스 항목은 커스텀 NewsCard 위젯으로 표현됩니다.

사진 갤러리 앱

GridView.builder(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 3,
    crossAxisSpacing: 4,
    mainAxisSpacing: 4,
  ),
  itemCount: photos.length,
  itemBuilder: (context, index) {
    return Image.network(photos[index].url, fit: BoxFit.cover);
  },
)
  • 이 코드는 사진들을 3열 그리드 형태로 표시합니다. 각 사진은 네트워크에서 로드됩니다.

ListView와 GridView의 고급 기능

무한 스크롤 구현

  • 무한 스크롤을 구현하려면 ScrollController를 사용하여 스크롤 위치를 감지하고, 필요할 때 새로운 데이터를 로드할 수 있습니다:
class InfiniteListView extends StatefulWidget {
  @override
  _InfiniteListViewState createState() => _InfiniteListViewState();
}

class _InfiniteListViewState extends State<InfiniteListView> {
  List<String> items = List.generate(20, (index) => "Item $index");
  ScrollController _scrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(() {
      if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
        _loadMoreData();
      }
    });
  }

  void _loadMoreData() {
    setState(() {
      items.addAll(List.generate(10, (index) => "Item ${items.length + index}"));
    });
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      controller: _scrollController,
      itemCount: items.length,
      itemBuilder: (context, index) {
        return ListTile(title: Text(items[index]));
      },
    );
  }
}

당겨서 새로고침 기능 추가

  • RefreshIndicator 위젯을 사용하여 당겨서 새로고침 기능을 쉽게 구현할 수 있습니다:
RefreshIndicator(
  onRefresh: () async {
    // 데이터 새로고침 로직
    await Future.delayed(Duration(seconds: 2));
    setState(() {
      items = List.generate(20, (index) => "Refreshed Item $index");
    });
  },
  child: ListView.builder(
    itemCount: items.length,
    itemBuilder: (context, index) {
      return ListTile(title: Text(items[index]));
    },
  ),
)

맺음말

  • ListView와 GridView는 Flutter에서 스크롤 가능한 레이아웃을 만드는 데 필수적인 위젯들입니다.
  • 이들을 효과적으로 활용하면 다양한 종류의 데이터를 효율적으로 표시하고 관리할 수 있습니다.
  • 기본적인 사용법부터 성능 최적화, 무한 스크롤, 새로고침 기능 등의 고급 기능까지 이해하고 적용함으로써, 사용자 경험이 뛰어난 앱을 개발할 수 있습니다.
  • 다음 포스팅에서는 SingleChildScrollView 와 CustomScrollView 위젯 강좌로 돌아오도록 하겠습니다.
반응형