본문 바로가기

dev/flutter

CustomScrollView

앱 화면에서 스크롤할 때 앱바가 사라지는 기능을 만들어야 하는데 ListView로는 해결이 되지 않아 CustomScrollView라는 것을 사용해야 했다. 더불어 여러가지의 스크롤뷰들을 사용할 때도 사용한다.

 

여기서 sliver라는 단어가 나오는데 스크롤할 때의 하나하나 조각요소들을 sliver라고 하는 것 같다.

(ListView도 내부에는 sliver를 가지고 있다고 한다.)

 

CustomScrollView는 Sliver~가 붙은 위젯만 사용할 수 있다.

아래에서 Sliver위젯들을 알아보자

 

 

 

SliverAppBar

앱바를 표현할 수 있는 위젯이다.

 

pinned : 화면을 스크롤 할 때 앱바가 줄어드는데 이 때 최소한의 앱바 크기만큼은 남겨두고 줄어 든다.

floating : 화면 스크롤 위치가 제일 처음으로 오지 않아도 앱바가 다시 늘어나게 된다.

snap : 조금만 스크롤해도 앱바 크기가 자동으로 최소 또는 최대가 된다. floating 속성이 false라면 false 값만 가질 수 있다 (오류 남)

expandedHeight : 앱바가 최대로 늘어났을 때 크기

collapsedHeight : 앱바가 줄어들었을 때 살아있을 크기인다. pinned 속성이 true일 때 보인다.

flexibleSpace : 앱바가 늘어난 경우 나오는 위젯이다. 흔히 이미지가 들어간다. FlexibleSpaceBar 위젯에서 collapseMode속성을 이용해 사라지는 애니메이션을 정할 수 있다.

 

 

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          const SliverAppBar(
            pinned: false,
            floating: true,
            snap: true,
            expandedHeight: 200.0,
            collapsedHeight: 100.0,
            flexibleSpace:
              FlexibleSpaceBar( 
                title: Text('Sliver App Bar'),
                background: FlutterLogo(),
                collapseMode: CollapseMode.parallax,
              ),
          ),
        ],
      )
    );
  }

 

 

 

SliverList

리스트뷰이다. SliverAppBar와 함께 많이 쓰인다.

 

delegate 속성으로 SliverChildListDelegate()와 SliverChildBuilderDelegate() 를 선택할 수 있다.

SliverChildListDelegate는 리스트로 나타낼 위젯들을 children으로 나열하는 것이다.

SliverChildBuilderDelegate는 나타낼 리스트 수만큼 위젯들을 만들어낸다.

SliverChildBuilderDelegate를 더 많이 사용하는 것 같다.

 

// SliverChildListDelegate
SliverList(
    delegate: SliverChildListDelegate(
      [
        ListTile(title: Text("Item")),
        ListTile(title: Text("Item")),
        ListTile(title: Text("Item")),
        ...
      ]
    )
  )
  
 
// SliverChildBuilderDelegate
SliverList(
    delegate: SliverChildBuilderDelegate(
      (context, index) {
        return ListTile(
          title: Text("Item $index")
        );
      },
      childCount: 100,
    ),

 

 

 

 

SliverToBoxAdapter

Container, Text 등 단일 위젯을 나타내고 싶을 때 사용한다. 수직 리스트 사이에 수평 리스트를 넣을 때 사용하면 좋다.

child 속성을 이용해 넣고싶은 위젯을 넣으면 된다.

 

SliverToBoxAdapter(
    child: SizedBox(
      height: 100.0,
      child: ListView.builder(
          scrollDirection: Axis.horizontal,
          itemCount: 20,
          itemBuilder: (context, index) {
            return SizedBox(
              width: 100.0,
              child: Card(
                color: Colors.primaries[Random().nextInt(Colors.primaries.length)],
                child: Center(
                  child: Text("box $index")
                ),
              ),
            );
          }),
    ),
  ),

 

 

 

 

SliverGrid

그리드뷰를 나타낼 때 사용한다.

GridView.builder위젯을 사용할 때와 동일하게 사용하면 된다.

 

SliverGrid(
    delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
        return Container(
            color: Colors.primaries[Random().nextInt(Colors.primaries.length)],
        );
      },
      childCount: 20,
    ),
    gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( // 그리드 옵션(필수)
      crossAxisCount: 5, // 한 행의 아이템 수 - 필수값
      // crossAxisSpacing: 10, // 아이템 세로 간격
      // mainAxisSpacing: 10, // 아이템 가로 간격
      // mainAxisExtent: 200, // 아이템 가로 길이
      // childAspectRatio: 2 // 아이템 비율 - 가로 / 세로
    )
  ),

 

 

 

 

SliverFillRemaining

리스트 중간에 Expanded같이 남은 여백을 채우고 싶을 때 사용하면 된다.

hasScrollBody를 이용해서 여백보다 위젯이 크다면 스크롤이 되게끔 해준다.

 

SliverFillRemaining(
    hasScrollBody: false,
    child: Container(
      color: Colors.primaries[Random().nextInt(Colors.primaries.length)],
      child: const Center(
        child: Text("fill area")
      ),
    ),
  ),

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'dev > flutter' 카테고리의 다른 글

SliverAppBar 높이 파악하기 (RenderObject)  (0) 2023.05.19
파이어베이스 dynamic links  (0) 2023.05.17
Flutter Web ListView 수평 scroll이 안될 때  (0) 2023.04.26
Dio  (0) 2023.04.23
Flutter 라우트  (0) 2023.04.20