일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- scroll
- Flutter
- Kotlin
- Button
- data
- 앱
- binding
- textview
- CustomScrollView
- Navigation
- LifeCycle
- 테스트
- Dialog
- TEST
- appbar
- textfield
- Coroutines
- intent
- viewmodel
- 안드로이드
- livedata
- Compose
- activity
- DART
- 계측
- drift
- ScrollView
- 앱바
- android
- tabbar
- Today
- Total
Study Record
[Flutter] CustomScrollView 본문
✍ CustomScrollView
여러 종류의 리스트 뷰를 한 번에 사용할 수 있는 위젯이다. 한 스크롤에 여러 가지 형태의 리스트뷰(그리드 뷰, 리스트 뷰 등)를 집어넣을 수 있다. CustomSctollView 에 slivers 인자에 넣고 싶은 리스트 뷰를 넣으면 되는데 ListView, GridView 를 사용할 수 없고 SliverList, SliverGrid 로 넣어야 한다. 단일 위젯을 넣고 싶다면 SliverToBoxAdapter 위젯을 사용한다.
CustomScrollView({
Key? key,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController? controller,
bool? primary,
ScrollPhysics? physics,
ScrollBehavior? scrollBehavior,
bool shrinkWrap = false,
Key? center,
double anchor = 0.0,
double? cacheExtent,
List slivers = const [],
int? semanticChildCount,
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
String? restorationId,
Clip clipBehavior = Clip.hardEdge,
})
SliverList, SliverGrid 모두 delegate 인자가 필요한데 둘 모두 SliverChildBuilderDelegate() 와 SliverChildListDelegate() 둘 중 하나를 사용할 수 있다. 사용 방법은 SliverList 와 SliverGrid 모두 같아서 복사해서 사용해도 된다.
SliverChildListDelegate() 는 리스트 항목을 한 번에 생성하기 때문에 비용이 많이 들 수 있다. 반면에 SliverChildBuilderDelegate() 는 화면에 보이는 항목을 기준으로 몇 개만 생성하기 때문에 SliverChildListDelegate() 보다 비용적인 면에서 이득일 수 있다.
SliverGrid(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(height: 300, child: Center(child: Text("$index")));
},
childCount: 100,
),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
);
SliverList(
delegate: SliverChildListDelegate(
List.generate(100, (index) => index)
.map((e) => Container(
height: 300,
child: Center(child: Text("$e"))
))
.toList(),
),
)
😶 SliverList (ListView)
CustomScrollView 에 ListView 를 넣으려면 SliverView 로 넣어야 한다. 위에서 설명했듯 delegator 인자를 상황에 맞게 사용하면 된다.
CustomScrollView(
slivers: [
SliverList(
delegate: SliverChildListDelegate(
List.generate(100, (index) => index)
.map((e) => Container(
height: 300,
child: Center(child: Text("$e"))
))
.toList(),
),
),
]
);
😶 SliverGrid(GridView)
CustomScrollView() 에 GridView 를 넣으려면 SliverGrid 로 넣어야 한다. delegator 인자를 상황에 맞게 사용하면 된다.
CustomScrollView(
slivers: [
SliverGrid(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(height: 300, child: Center(child: Text("$index")));
},
childCount: 100,
),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
),
]
);
😶 SliverGrid + SliverList
CustomScrollView(
slivers: [
SliverGrid(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
color: Colors.black,
child: Center(child: Text("$index")),
);
},
childCount: 20,
),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 12.0,
crossAxisSpacing: 12.0,
),
),
SliverList(
delegate: SliverChildListDelegate(
List.generate(10, (index) => index)
.map((e) => Container(
height: 300,
margin: const EdgeInsets.all(16.0),
color: Colors.deepOrangeAccent,
child: Center(child: Text("$e")),
),
)
.toList(),
),
),
]
);
😶 SliverToBoxAdapter
CustomScrollView 의 slivers 에 리스트 뷰의 형태로 넣는 것 말고 단일 위젯을 사용하고 싶을 때 SliverToBoxAdapter() 위젯을 사용한다.
CustomScrollView(
slivers: [
...,
SliverToBoxAdapter(
child: Column(...),
),
],
)
✍ CustomScrollView parameter
다른 파라미터에 대해 소개하자면 다음과 같다.
😶 가로 스크롤 vs 세로 스크롤(default)
scrollDirection 인자로 세로 스크롤(Axis.vertical), 가로 스크롤(Axis.horizontal)을 정할 수 있다. 세로 스크롤일 때는 세로와 관련된 위젯(ex. Column) 가로 스크롤일때는 가로와 관련된 위젯(ex. Row)을 사용해야 한다. 기본 값은 Axis.vertical 이다.
CustomScrollView(
scrollDirection: Axis.horizontal,
scrollDirection: Axis.vertical,
);
😶 키보드 컨트롤
keyboardDismissBehavior 인자를 사용하면 SingleChildScrollView 에 TextField 와 같이 입력 폼이 포함될 때, 사용자가 TextField 를 클릭 시 키보드가 올라왔을 때 스크롤 시 키보드가 자동으로 내려갈지(manual) 아니면 온전히 사용자에 맡길지(스크롤 시 자동으로 키보드가 내려가지 않음, onDrag) 정할 수 있다.
CustomScrollView(
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.manual
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag
);
😶 스크롤 모양
physics 인자를 사용하면 스크롤 모양을 설정할 수 있다.
인자(physics) | 설명 |
NeverScrollableScrollPhysics | 사용자가 스크롤 불가능하다. |
AlwaysScrollableScrollPhysics | 항상 사용자가 스크롤을 가능하게 하고 스크롤 모양은 기종 기본값을 따른다. |
BouncingScrollPhysics | IOS 기본 스크롤 모양으로, 튕기는 모양이다. |
ClampingScrollPhysics | AOS 기본 스크롤 모양이다. |
PageScrollPhysics | 페이지 단위로 스크롤할 수 있다. |
CustomScrollView(
physics: AlwaysScrollableScrollPhysics(),
);
+ BouncingScrollPhysics 가 적용된 상태에서 위젯이 화면 크기보다 작을 때 스크롤 시 잘려 보일 수 있다. clipBehavior 를 Clip.none 로 하면 위젯이 잘리지 않으면서 튕기는 스크롤 모양이 된다.
CustomScrollView(
physics: AlwaysScrollableScrollPhysics(),
clipBehavior: Clip.none,
...
);
'Flutter > widget_scrollView' 카테고리의 다른 글
[Flutter] SliverPersistentHeader (스크롤 중 위젯 고정) (0) | 2023.03.09 |
---|---|
[Flutter] CustomScrollView 에서 앱바 컨트롤하기(숨김, 고정 등) - SliverAppBar (0) | 2023.03.08 |
[Flutter] ReorderableListView (0) | 2023.03.08 |
[Flutter] GridView (0) | 2023.03.08 |
[Flutter] ListView (0) | 2023.03.07 |