Custom Scroll View in Flutter: A Guide
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.
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 likeSizedBox
,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.