두 위젯 CustomScrollView
와 SliverAppBar
는 Flutter에서 스크롤 가능한 영역을 더 유연하게 구성할 때 유용합니다. 아래에서 두 위젯에 대한 설명을 제공하겠습니다.
CustomScrollView
는 여러 개의 스크롤 가능한 영역을 조합해서 사용하려 할 때 유용한 위젯입니다.ListView
나 GridView
와는 달리 CustomScrollView
는 그 자체로 아이템이나 자식들을 가지지 않습니다. 대신 slivers라는 속성을 통해 여러 sliver 위젯들을 자식으로 가질 수 있습니다."Sliver"는 Flutter에서 사용하는 용어로, 특별한 종류의 스크롤 가능한 영역을 나타냅니다. 기본적으로, sliver는 스크롤 가능한 영역에서 여러 부분으로 나눌 수 있는 작은 조각(piece)을 의미합니다.
Flutter에서 "sliver"의 개념은 기본 ListView
또는 GridView
와 같은 일반 스크롤 가능한 영역보다 더 정교한 스크롤 작업을 수행할 수 있도록 합니다. 예를 들어, 사용자가 스크롤할 때 헤더가 축소되는 효과나 동적으로 아이템이 배치되는 레이아웃 등을 구현하기 위해 sliver 위젯을 사용할 수 있습니다.
Flutter에는 다양한 sliver 위젯이 포함되어 있습니다. 예를 들면:
SliverList
: 일반 리스트와 유사하게 아이템을 세로로 나열합니다.SliverGrid
: 그리드 형태의 아이템 배치를 지원합니다.SliverAppBar
: 스크롤에 반응하는 앱 바입니다.SliverToBoxAdapter
: 단일 위젯을 sliver로 변환합니다.이러한 sliver 위젯들은 주로 CustomScrollView
내에서 사용되며, 이를 통해 다양한 스크롤 효과와 레이아웃을 구현할 수 있습니다.
요약하면, "sliver"는 Flutter에서 스크롤 가능한 영역의 작은 부분 또는 조각을 나타내며, 이를 활용하면 다양하고 정교한 스크롤 작업을 수행할 수 있습니다.
SliverAppBar
는 CustomScrollView
의 일부로 사용되며, 스크롤 행동에 따라 애니메이션 효과를 적용할 수 있는 앱 바입니다.pinned
: true
로 설정하면 작은 앱 바로 축소되지만 스크롤 영역의 상단에 '고정'됩니다.
floating
: 이 속성이 true
로 설정되면, 사용자가 스크롤을 시작할 때 SliverAppBar
가 즉시 나타나게 됩니다. 일반적으로 사용자가 목록의 맨 위로 돌아갈 필요 없이 스크롤을 조금만 움직여도 SliverAppBar
를 빠르게 다시 볼 수 있게 하려고 사용합니다. 반면에 floating
이 false
로 설정되면, 사용자는 스크롤 위치를 목록의 맨 위로 되돌려야만 SliverAppBar
를 다시 볼 수 있습니다.
expandedHeight
: 앱 바가 확장될 때의 최대 높이입니다.
flexibleSpace
: 확장 가능한 공간 안에 배치될 위젯, 예를 들면 배경 이미지 등을 설정할 때 사용합니다.
CustomScrollView(
slivers: <Widget>[
SliverAppBar(
expandedHeight: 200.0,
floating: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
title: Text("SliverAppBar Example"),
background: Image.network(
"https://some-image-url.com",
fit: BoxFit.cover,
),
),
),
// 다른 slivers...
],
)
이 예제에서는 SliverAppBar
가 CustomScrollView
의 일부로 사용되고 있으며, 앱 바는 확장될 때 200 픽셀의 높이를 가집니다. 또한 앱 바는 스크롤 영역의 상단에 항상 고정되어 있습니다. FlexibleSpaceBar
를 사용하여 앱 바에 제목과 배경 이미지를 추가하였습니다.
import 'package:flutter/material.dart';
import 'package:tiktok_clone/constants/sizes.dart';
class UserProfileScreen extends StatefulWidget {
const UserProfileScreen({super.key});
State<UserProfileScreen> createState() => _UserProfileScreenState();
}
class _UserProfileScreenState extends State<UserProfileScreen> {
Widget build(BuildContext context) {
return CustomScrollView(
slivers: [
SliverAppBar(
pinned: true,
stretch: true,
backgroundColor: Colors.teal,
collapsedHeight: 80,
expandedHeight: 200,
flexibleSpace: FlexibleSpaceBar(
stretchModes: const [
StretchMode.blurBackground,
StretchMode.zoomBackground,
StretchMode.fadeTitle,
],
background: Image.asset(
"assets/images/placeholder.jpg",
fit: BoxFit.cover,
),
title: const Text("Hello!"),
),
),
SliverFixedExtentList(
delegate: SliverChildBuilderDelegate(
childCount: 50,
(context, index) => Container(
color: Colors.amber[100 * (index % 9)],
child: Align(
alignment: Alignment.center,
child: Text("Item $index"),
),
),
),
itemExtent: 100,
),
SliverGrid(
delegate: SliverChildBuilderDelegate(
childCount: 50,
(context, index) => Container(
color: Colors.blue[100 * (index % 9)],
child: Align(
alignment: Alignment.center,
child: Text("Item $index"),
),
),
),
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 100,
mainAxisSpacing: Sizes.size20,
crossAxisSpacing: Sizes.size20,
childAspectRatio: 1,
),
)
],
);
}
}
이 코드는 Flutter에서 사용자 프로필 화면을 구성하는 예제입니다. 코드에는 주로 CustomScrollView
, SliverAppBar
및 SliverFixedExtentList
위젯이 사용되었습니다. 이 코드의 구성 요소에 대해 상세히 설명하겠습니다.
UserProfileScreen:
StatefulWidget
기반의 사용자 프로필 화면입니다._UserProfileScreenState
를 사용합니다.CustomScrollView:
SliverAppBar:
snap
, floating
, pinned
, stretch
속성들이 사용되어 다양한 애니메이션 및 동작을 설정합니다.collapsedHeight
는 앱 바가 축소될 때의 높이를, expandedHeight
는 앱 바가 확장될 때의 높이를 지정합니다.flexibleSpace
는 FlexibleSpaceBar
를 사용하여 앱 바 내에서 동적으로 크기가 조정되는 공간을 정의합니다.SliverAppBar
는 사용자의 스크롤에 따라 그 동작과 모양이 변하는 매우 유연한 앱 바 위젯입니다. 코드 스니펫에서 snap
, floating
, pinned
, stretch
속성들은 SliverAppBar
의 동작 방식을 제어합니다. 각 속성에 대해 살펴보겠습니다:snap
이 true
로 설정되면, 스크롤이 멈추었을 때 앱 바가 완전히 나타나거나 완전히 사라집니다. 이 속성은 floating
도 true
로 설정된 경우에만 효과가 있습니다.floating
앱 바는 사용자가 위로 스크롤하기 시작하면 바로 보이게 됩니다. 스크롤 뷰의 시작 부분에 도달할 필요가 없습니다.pinned
가 true
일 때, 앱 바는 스크롤 뷰 상단에 계속 보이게 됩니다. 하지만 앱 바의 나머지 내용은 스크롤과 함께 사라지고 도구 모음 부분만 남습니다.stretch
가 활성화되면, 사용자가 상단에서 오버 스크롤할 때 앱 바가 늘어나고 크기가 확장됩니다.snap: true
, floating: true
, pinned: true
, stretch: true
를 함께 사용하면 SliverAppBar
는:
이 조합은 사용자 상호작용에 따라 조정되는 매우 동적이고 상호작용적인 앱 바를 만들어내며, 화면 공간 최대화와 사용자 경험을 우선시하는 현대 모바일 애플리케이션에서 일반적으로 사용되는 패턴입니다.
FlexibleSpaceBar:
stretchModes
는 앱 바가 확장될 때 어떤 방식으로 확장될 것인지를 정의합니다. 여기서는 배경 흐리게하기, 배경 확대, 제목 사라지게하기 등의 모드가 사용되었습니다.background
에서는 배경 이미지를 설정합니다.SliverFixedExtentList:
delegate
는 리스트의 아이템들을 구성하기 위해 SliverChildBuilderDelegate
를 사용하여 50개의 아이템을 생성합니다.itemExtent
는 각 아이템의 높이를 지정합니다.이 코드를 실행하면, 사용자는 상단의 유연한 앱 바를 볼 수 있으며, 확장 및 축소 애니메이션 효과가 적용됩니다. 아래쪽에는 50개의 아이템이 고정된 높이로 표시되는 리스트가 있습니다.
SliverFixedExtentList
는 Flutter에서 스크롤 가능한 영역 내에 고정된 높이를 가진 아이템들로 구성된 리스트를 생성하는 위젯입니다. Sliver 위젯들은 CustomScrollView
내에서 사용될 수 있습니다.
SliverFixedExtentList
의 주요 특징과 속성을 상세하게 살펴보겠습니다:
기본 개념:
SliverFixedExtentList
는 모든 자식 아이템들이 동일한 높이를 가질 것이라는 가정하에 최적화된 스크롤 가능한 리스트를 제공합니다. 각 아이템의 높이가 동일하기 때문에 Flutter는 더 빠르게 스크롤 및 렌더링 작업을 수행할 수 있습니다.itemExtent:
delegate:
SliverChildBuilderDelegate
또는 SliverChildListDelegate
를 사용하여 아이템들을 정의합니다.SliverChildBuilderDelegate
를 사용하면 지연 로딩이 가능하며, 요청 시점에 각 아이템을 생성할 수 있습니다. 따라서 무한한 수의 아이템이나 매우 큰 수의 아이템을 갖는 리스트를 생성할 때 유용합니다.사용 사례:
SliverFixedExtentList
를 사용하여 50개의 아이템을 생성합니다. 각 아이템은 SliverChildBuilderDelegate
에 의해 생성되며, 다양한 색상의 컨테이너로 표시됩니다. 아이템의 중앙에는 "Item $index"라는 텍스트가 표시됩니다.이 위젯은 특히 아이템의 크기가 동일한 경우나 리스트의 크기가 동적으로 변하지 않는 경우에 유용하게 사용됩니다. 동일한 높이의 아이템으로 구성된 리스트를 빠르게 스크롤하고 렌더링해야 하는 경우에는 SliverFixedExtentList
가 효율적인 선택이 될 수 있습니다.