출처: https://medium.com/flutter/slivers-demystified-6ff68ab0296f
많은 사람들이 Sliver를 어려워 하지만 Sliver는 Scrollable 영역의 일부일 뿐이다. ListView와 GridView 같은 모든 Scrollable 위젯들의 내부는 Sliver로 구현되어 있다. Sliver를 Scrollable 영역에서 세밀한 제어를 하기 위한 로우레벨 인터페이스라고 생각하면 된다. Sliver는 각 아이템의 빌드를 화면 안으로 스크롤 되는 시점에 늦게(lazily) 진행할 수 있기 때문에 특히 많은 수의 자식 위젯들을 효과적으로 스크롤 할 때 유용하다.
예를 들어 다음과 같은 스크롤 액션이 필요할 수 있다.
모든 Sliver 컴포넌트들은 CustomScrollView 안에 있다. 나머지는 어떻게 Sliver들의 리스트를 조합해 Scrollable 영역을 구성하냐에 달려있다. SliverList로 ListView를 만드는 것과 같이 말이다.
SliverList는 delegate
파라미터로 화면에서 스크롤 될 리스트에 들어갈 아이템들을 전달 받는다. SliverChildListDelegate
를 통해 실제 리스트를 전달할 수도 있고 SliverChildBuilderDelegate
로 동적으로 리스트를 빌드할 수도 있다.
// 명시적으로 위젯 리스트 전달. 위젯들이 이미 생성된 상태이기 때문에 효율성 절감 효과는 없다.
SliverList(
delegate: SliverChildListDelegate(
[
Container(color: Colors.red, height: 150.0),
Container(color: Colors.purple, height: 150.0),
Container(color: Colors.green, height: 150.0),
],
),
);
// 다른 색을 가진 Container를 가진 무한 스크롤 리스트를 동적으로 빌드.
SliverList(
delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
// To convert this infinite list to a list with three items,
// uncomment the following line:
// if (index > 3) return null;
return Container(color: getRandomColor(), height: 150.0);
},
// Or, uncomment the following line:
// childCount: 3,
),
);
SliverList와 유사하지만 대각 크기(세로 스크롤이면 너비, 가로 스크롤이면 높이 크기)를 추가적으로 지정한다. 대각 크기를 지정하는 방법은 세 가지가 있다.
SliverGrid.count(children: scrollItems, crossAxisCount: 4)
SliverGrid.extent(children: scrollItems, maxCrossAxisExtent: 90.0)
gridDelegate
를 명시적으로 전달한다.SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return new Container(
color: randomColor(),
height: 150.0);
}
);
SliverAppBar로 멋진 AppBar를 만드는 방법은 flexibleSpace
와 exandedHeight
파라미터를 지정하는 것이다. 두 개를 지정하는 것으로 펼쳐졌을 때와 접혔을 때 각각 다른 높이와 모습을 가진 AppBar를 만들 수 있다.
// 펼쳐졌을 때는 높이 200의 이미지가 들어간 모양, 접혔을 때는 초록색의 텍스트가 들어간 모양의 AppBar
SliverAppBar(
title: Text('SliverAppBar'),
backgroundColor: Colors.green,
expandedHeight: 200.0, //펼쳐졌을 때의 높이
floating: ture // true일 경우 스크롤을 내렸을 때 리스트의 맨 위에 있지 않더라고 AppBar가 표시된다.
snap: true // floating이 true일 때만 사용 가능. floating 중에 손을 떼면 true일 경우
//AppBar의 크기가 max, min 값 중 가까운 값으로 바뀌고(펼쳐지거나 접힌다는 뜻)
//false 일 경우 그대로 멈춤.
// 펼쳐 졌을 때 보여질 위젯
flexibleSpace: FlexibleSpaceBar(
background: Image.asset('assets/forest.jpg', fit: BoxFit.cover),
),
),