본문 바로가기
Flutter

Flutter DraggableScrollableSheet 위젯 : 스와이프 가능한 화면 구현하는 법

by 김무스비 2024. 11. 2.
728x90
반응형

Flutter 애플리케이션을 개발하다 보면 화면의 특정 섹션을 스와이프하여 확장하거나 축소하고 싶은 상황이 자주 있습니다. 이런 기능은 특히 모달(sheet) 형태의 UI나 세부 정보를 사용자에게 보여줄 때 유용합니다. 이때 활용할 수 있는 위젯이 바로 DraggableScrollableSheet입니다. DraggableScrollableSheet는 사용자가 드래그하여 화면의 크기를 조정할 수 있는 위젯으로, 애플리케이션 내에서 직관적이고 편리한 사용자 경험을 제공합니다. 이번 글에서는 DraggableScrollableSheet의 사용법과 속성, 실제 예제를 통해 이 위젯을 어떻게 구현하고 활용할 수 있는지 자세히 알아보겠습니다.

draggable image


1. DraggableScrollableSheet란?

DraggableScrollableSheet는 Flutter의 위젯 중 하나로, 주로 화면 하단에서 시작하여 사용자가 드래그할 때 화면의 특정 부분을 확장하거나 축소할 수 있도록 도와줍니다. 이 위젯은 스와이프 제스처와 함께 드래그 가능한 스크롤 뷰를 생성하므로, 자연스러운 모달 레이아웃을 구성할 때 유용합니다. 일반적으로 검색 결과, 채팅 창, 설정 창 등과 같은 모달 요소를 만들 때 사용할 수 있습니다.

2. DraggableScrollableSheet 기본 사용법

DraggableScrollableSheet를 사용하기 위해서는 기본적으로 아래의 속성들을 설정합니다:

  • initialChildSize: 초기 시트의 높이를 0.0에서 1.0 사이의 값으로 설정합니다.
  • minChildSize: 시트가 최대로 축소되었을 때의 높이입니다.
  • maxChildSize: 시트가 최대로 확장되었을 때의 높이입니다.
  • builder: 실제 드래그 가능한 시트 내의 콘텐츠를 작성하는 부분으로, ScrollController를 포함해 리스트나 스크롤 가능한 위젯을 추가할 수 있습니다.

기본적인 DraggableScrollableSheet 예제는 다음과 같습니다.

Scaffold(
  body: Stack(
    children: [
      // 백그라운드 콘텐츠
      Center(child: Text("Main Content")),
      
      // DraggableScrollableSheet
      DraggableScrollableSheet(
        initialChildSize: 0.2, // 초기 높이
        minChildSize: 0.1,     // 최소 높이
        maxChildSize: 0.8,     // 최대 높이
        builder: (context, scrollController) {
          return Container(
            color: Colors.blue[100],
            child: ListView.builder(
              controller: scrollController, // 스크롤 컨트롤러
              itemCount: 30,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text("Item $index"),
                );
              },
            ),
          );
        },
      ),
    ],
  ),
)

위 코드에서는 DraggableScrollableSheet가 화면 하단에서 시작하여 사용자가 위아래로 스와이프하면 시트가 확장 또는 축소됩니다. 초기 높이는 0.2로 설정되었으며, 최대로 축소되면 0.1, 최대로 확장되면 0.8의 높이까지 확장됩니다. 내부에는 ListView.builder가 포함되어 스크롤 가능한 목록 형태로 구현되었습니다.

3. DraggableScrollableSheet 주요 속성 설명

(1) initialChildSize

initialChildSize는 DraggableScrollableSheet의 초기 높이를 설정하는 속성입니다. 0.0에서 1.0 사이의 값으로 설정하며, 0.5로 설정하면 화면의 절반 정도 높이로 시작하게 됩니다. 예를 들어, 초기 높이를 화면의 30%로 설정하고 싶다면 initialChildSize: 0.3으로 지정합니다.

(2) minChildSize

minChildSize는 DraggableScrollableSheet의 최소 높이를 설정합니다. 이 값은 드래그로 시트를 축소했을 때 허용할 최소 높이를 지정합니다. initialChildSize보다 작게 설정할 수 있으며, 예를 들어 minChildSize: 0.1로 설정하면 시트를 화면 높이의 10%까지 축소할 수 있습니다.

(3) maxChildSize

maxChildSize는 DraggableScrollableSheet의 최대 높이를 설정합니다. 시트가 드래그로 확장할 수 있는 최대 높이이며, maxChildSize: 1.0으로 설정하면 전체 화면까지 확장할 수 있습니다.

(4) builder

builder 속성은 DraggableScrollableSheet의 메인 콘텐츠를 작성하는 곳으로, 스크롤 가능한 위젯과 ScrollController를 함께 사용하여 콘텐츠를 배치합니다.

builder: (context, scrollController) {
  return ListView.builder(
    controller: scrollController,
    itemCount: 20,
    itemBuilder: (context, index) {
      return ListTile(
        title: Text("Item $index"),
      );
    },
  );
}

4. DraggableScrollableSheet 활용 예제

(1) 스와이프 가능한 뉴스 피드 구현

DraggableScrollableSheet를 사용해 하단에서 뉴스 목록이 나타나고 스와이프할 수 있는 뉴스 피드를 구현할 수 있습니다.

Scaffold(
  body: Stack(
    children: [
      Center(child: Text("Flutter App Background")), // 메인 콘텐츠
      
      DraggableScrollableSheet(
        initialChildSize: 0.3,
        minChildSize: 0.1,
        maxChildSize: 0.7,
        builder: (context, scrollController) {
          return Container(
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
            ),
            child: ListView.builder(
              controller: scrollController,
              itemCount: 15,
              itemBuilder: (context, index) {
                return ListTile(
                  leading: Icon(Icons.article),
                  title: Text("News Headline $index"),
                  subtitle: Text("Description of news headline $index"),
                );
              },
            ),
          );
        },
      ),
    ],
  ),
)

위 예제에서는 DraggableScrollableSheet 위젯을 뉴스 피드 용도로 사용하여, 사용자가 스와이프하여 필요한 뉴스 목록을 확인하고 쉽게 축소하거나 확장할 수 있습니다.

(2) 하단 메뉴를 통한 상품 리스트 제공

상품 리스트 화면에서 제품들을 리스트 형식으로 제공하며, DraggableScrollableSheet를 통해 하단에서 스와이프하여 선택할 수 있는 UX를 제공할 수 있습니다.

Scaffold(
  body: Stack(
    children: [
      Center(child: Text("Product List Background")), // 메인 콘텐츠
      
      DraggableScrollableSheet(
        initialChildSize: 0.2,
        minChildSize: 0.1,
        maxChildSize: 0.5,
        builder: (context, scrollController) {
          return Container(
            color: Colors.grey[200],
            child: GridView.builder(
              controller: scrollController,
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 2,
                crossAxisSpacing: 4.0,
                mainAxisSpacing: 4.0,
              ),
              itemCount: 8,
              itemBuilder: (context, index) {
                return Card(
                  child: Center(child: Text('Product $index')),
                );
              },
            ),
          );
        },
      ),
    ],
  ),
)

5. DraggableScrollableSheet 사용 시 주의 사항

  • DraggableScrollableSheet는 스와이프에 의해 사용자가 직접 컨트롤할 수 있는 만큼, 콘텐츠의 복잡도와 양을 신경 써야 합니다. 너무 많은 콘텐츠가 포함될 경우 스크롤이 매끄럽지 않을 수 있습니다.
  • DraggableScrollableSheet의 initialChildSize, minChildSize, maxChildSize 값을 잘 조절하여 UX를 최적화해야 합니다. 특히, 콘텐츠의 중요도에 따라 초기 크기와 확장 가능 범위를 설정하는 것이 좋습니다.
  • 스크롤 가능한 위젯(예: ListView, GridView)과 결합하여 사용할 때 scrollController를 꼭 설정해야 DraggableScrollableSheet의 드래그와 함께 스크롤 기능이 정상적으로 동작합니다.

결론

Flutter의 DraggableScrollableSheet 위젯을 사용하면 스와이프 가능하고 반응형인 UI를 쉽게 구현할 수 있습니다. 이를 통해 모달 창, 뉴스 피드, 하단 메뉴 등 다양한 형태의 사용자 경험을 제공할 수 있으며, initialChildSize, minChildSize, maxChildSize 같은 속성을 조절하여 원하는 레이아웃을 만들 수 있습니다. DraggableScrollableSheet로 유연하고 직관적인 앱을 설계해 보세요!

728x90
반응형