[Flutter] CustomScrollView with DefaultTabController

이선행·2024년 4월 19일

CustomScrollView는 Sliver를 사용하여 리스트 형태로 유연하게 보여줄 수 있는 위젯이다(NestedScrollView도 Sliver를 사용할 수 있는 위젯이다.)
요즘 개발되는 앱들은 대부분 CustomScrollView를 사용하여 개발하는것 같다.

CustomScrollView와 DefaultTabController를 사용해서 여러 TabBarView가 스크롤 되게 구현할 수 있다.

Tabbar등을 사용하기 위해선 상위에 Scaffold나 Material로 감싸줘야 한다.
위젯 하나하나 작성하지는 않고 뼈대만 적어 놓겠습니다.
이런 구성으로 하면 된다 라는 느낌만 가져가면 된다.
*AppBar나 TabBarView같은 위젯 내용은 원하는 대로 만들어서 넣어주면 된다.

Scaffold(
	body : DefaulTabController(
    	length : 3
        child : CustomScrollView(
        	slivers : [
            	SliverAppBar(),										//AppBar는 자신이 직접 만들어서 넣어주면 된다
                
                SliverPersistenHeader(delegate : TabBarDelegate()), //여기에 TabBar가 들어간다.
                
                SLiverFillRemaining(								//이 부분이 TabBarView
                	child : TabBarView(
                    	children : [
                        	//CustomScrollView 하나가 한개의 탭 
                            //지금은 Container 한개밖에 없지만 자신이 원하는 대로 다시 구성하면 된다.
                        	CustomScrollView(
                            	Slivers : [
                                	SliverToBoxAdapter(
                                    	child : Container(
                                        	height : 200,
                                        	color : Colors.red),
                                            ),
                                		],
                                	),
                                ),
                            CustomScrollView(
                            	Slivers : [
                                	SliverToBoxAdapter(
                                    	child : Container(
                                        	height : 200,
                                        	color : Colors.blue),
                                            ),
                                		],
                                	),
                                ),
                           CustomScrollView(
                            	Slivers : [
                                	SliverToBoxAdapter(
                                    	child : Container(
                                        	height : 200,
                                        	color : Colors.white),
                                            ),
                                		],
                                	),
                                )
            	]))
                
class TabBarDelegate extends SliverPersistentHeaderDelegate {
  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    // TODO: implement build
    return TabBar(
      labelColor: $styles.colors.colorPrimaryBlack,
      labelStyle: $styles.textStyles.headline04
          .copyWith(fontWeight: FontWeight.w600, fontSize: 16),
      unselectedLabelColor: $styles.colors.colorTextGuideGrey,
      unselectedLabelStyle: $styles.textStyles.headline04
          .copyWith(fontWeight: FontWeight.w500, fontSize: 16),
      splashBorderRadius: BorderRadius.circular(12),
      overlayColor: const MaterialStatePropertyAll(Colors.transparent),
      indicatorColor: $styles.colors.colorMainPrimaryGreen,
      indicatorSize: TabBarIndicatorSize.tab,
      indicatorWeight: 2,
      tabs: const [
        Tab(
          text: 'Tab1',
        ),
        Tab(
          text: 'Tab2',
        ),
        Tab(
          text: 'Tab3',
        ),
      ],
    );
  }

  @override
  // TODO: implement maxExtent
  double get maxExtent => 50;

  @override
  // TODO: implement minExtent
  double get minExtent => 50;

  @override
  bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
    return false;
  }
}

1개의 댓글

comment-user-thumbnail
2025년 7월 1일

안녕하세요. 혹시 이방법으로 instagram, thread와 같은 앱에서 profile 화면처럼 할 수 있을까요?
스크롤을하면 탭바는 고정이되고 스크롤이 컨텐츠양 만큼 되는 구현입니다..

답글 달기