Custom Scroll View in Flutter: A Guide

Karthik Ponnam
5 min readApr 12, 2023

--

Why ?

Why CustomScrollView right when my SingleChildScrollView is working without any issue.

Yes, I thought the same until i faced an issue with an app which i developed for one of my client. In the app i used Normal SingleChildScrollView so now i need a text above the scrollview and some other decorations so i used Column which wraps out scrollview.

Now first issue as our scrollview has unbounded height which causes issue so we use our simple fix right? shrinkWrap: true wow it works like charm and issue resolved. now list view won’t scroll so we need to wrap our Column inside a SingleChildScrollView that’s it now out scrollview is ready

Usually my clients app contains lots and lots of images. So now the crashing of my app happens when the list getting scrolled down and it gets added with new set of items in list and after few new items in the list my app just crashes 😿

So best solution i can come up with is to migrate my SingleChildScrollView to CustomScrollView and then all backs to normal.

Enough back story let’s see about CustomScrollView

CustomScrollView

CustomScrollView is a widget that provides a flexible way to create scrollable views with custom behavior. Using CustomScrollView,we can implement complex scrolling effects and create unique user experiences that cannot be implemented by default scrolling widgets like ListView or GridView.

Using CustomScrollView, we can define a sliver-based layout, which consists of sliver widgets, to create scrollable areas with different scroll effects.

A sliver is a portion of a scrollable area, such as a scrollable list or grid, that can be scrolled independently. Slivers can be used to create complex scrolling behaviors, such as sticky headers, parallax effects, and more. CustomScrollView is composed of multiple sliver widgets that are arranged in a scrollable layout.

https://api.flutter.dev/flutter/widgets/CustomScrollView-class.html

Creating a CustomScrollView

Step1:

Create a CustomScrollView widget. Start by creating a CustomScrollView widget as the parent widget that will hold our scrollable content. we can define the CustomScrollView with a slivers property, which is a list of sliver widgets that will be used to build the scrollable view.

CustomScrollView(
slivers: <Widget>[
// Add sliver widgets here
],
)

Step 2:

Add Sliver widgets. Inside the slivers property of CustomScrollView,we can add different sliver widgets to define the layout and behavior of our scroll view. Some commonly used sliver widgets are:

  • SliverAppBar: this widget used to create a sticky app bar that stays at the top of the scroll view or hides when scrolling down.
  • SliverList: this widget used to create a scrollable list of items in a linear arrangement.
  • SliverGrid: this widget used to create a scrollable grid of items in a two-dimensional arrangement.
  • SliverToBoxAdapter: this widget used to create a sliver that contains a single non-scrollable box widget. we can use this widget to render a non sliver widgets like SizedBox ,Container , Padding and more

Step 3:

We can define the scrolling behavior of our custom scroll view using various properties of the sliver widgets. For example, we can set the floating property of SliverAppBar to true to create a floating app bar that hides when scrolling down and reappears when scrolling up. we can also set the pinned property of SliverAppBar to true to create a pinned app bar that remains visible even when scrolling.

Example: Creating a Custom Scroll View with Floating AppBar

CustomScrollView(
slivers: <Widget>[
SliverAppBar(
floating: true,
title: Text('Sticky Headers'),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Column(
children: <Widget>[
Container(
height: 50,
color: Colors.grey,
alignment: Alignment.centerLeft,
padding: EdgeInsets.symmetric(horizontal: 16),
child: Text(
'Section $index',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
),
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: 10,
itemBuilder: (BuildContext context, int subIndex) {
return ListTile(
title: Text('Item $subIndex in Section $index'),
);
},
),
],
);
},
childCount: 5,
),
),
],
)

In above example, we used SliverAppBar as the floating at the top of our scroll view. We have set the floating property of SliverAppBar to true to make it to disappear as the user scrolls and snaps back in when user tries to scroll back.

Conclusion

CustomScrollView is a powerful widget in Flutter that allows us to create custom scroll views with unique behavior and appearance. By using different sliver widgets and customizing their properties, we can create complex scrolling effects and implement effetcs like sticky headers, parallax effects, and more.

Bonus: CustomScrollView with Header animation

CustomScrollView(
slivers: <Widget>[
SliverAppBar(
expandedHeight: 200, // Set the height of the header when expanded
flexibleSpace: FlexibleSpaceBar(
background: Stack(
fit: StackFit.expand,
children: <Widget>[
// Add the background image
Image.network(
'https://images.unsplash.com/photo-1469474968028-56623f02e42e?q=40',
fit: BoxFit.cover,
),
// Add the overlay with opacity
Container(
color: Colors.black.withOpacity(0.3),
),
// Add the title with scaling and fading effect
Align(
alignment: Alignment.bottomLeft,
child: Padding(
padding: EdgeInsets.only(left: 16, bottom: 16),
child: TweenAnimationBuilder<double>(
tween: Tween<double>(begin: 1.0, end: 0.0),
duration: Duration(milliseconds: 500),
builder: (BuildContext context, double value,
Widget? child) {
return Transform.scale(
scale: 1 + value, // Scale factor for the title
child: Opacity(
opacity:
1 - value, // Opacity factor for the title
child: Text(
'Parallax Header',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
);
},
),
),
),
],
),
),
// Other properties like pinned, floating, elevation, etc.
// can be customized as needed
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
// Build the list of items
return ListTile(
title: Text('Item $index'),
);
},
childCount: 20, // Number of items in the list
),
),
],
)

Thanks for your time.

Hope you like it, if yes clap & share.

--

--

Karthik Ponnam
Karthik Ponnam

Written by Karthik Ponnam

❤️ to Code. Full Stack Developer, Flutter, Android Developer, Web Development, Known Languages Java, Python so on.,

Responses (1)