Most of us have used applications that remember our scroll position when we leave a tab and come back later. Facebook is a classic example.
In Flutter, one straightforward way to get that behavior is to use PageStorageKey.
The secret is the key
Almost every Flutter widget accepts a Key. At a high level, keys help Flutter distinguish one widget instance from another. That matters because Flutter maintains internal trees to track widget state and position during rendering.
In this case, we can attach a PageStorageKey to a ListView so Flutter remembers how far the user has scrolled. If you want a deeper explanation of keys in general, see Flutter: Why are Keys important?.
ListView + PageStorageKey
Here is the simplest usage:
// ...
var data = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
// ...
@override
Widget build(BuildContext context) {
return ListView.builder(
key: PageStorageKey('key must be unique for each list view'),
itemCount: data.length,
itemBuilder: (ctx, index) => Padding(
padding: const EdgeInsets.symmetric(
vertical: 32.0,
),
child: ListTile(
title: Text(data[index]),
),
),
);
}
// ...
One important detail is that each ListView should receive its own unique PageStorageKey.
If you are using a ListView that contains ExpansionTiles, each ExpansionTile should also get its own unique PageStorageKey so Flutter can remember whether that tile is expanded or collapsed:
// ...
var data = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
// ...
@override
Widget build(BuildContext context) {
return ListView.builder(
key: PageStorageKey('key must be unique for each list view'),
itemCount: data.length,
itemBuilder: (ctx, index) => Padding(
padding: const EdgeInsets.symmetric(
vertical: 32.0,
),
child: ExpansionTile(
key: PageStorageKey('child key ' + index),
title: Text(data[index]),
children: [
Container(
color: Colors.red,
height: 100,
width: 100,
),
],
),
),
);
}
// ...
That small addition can make an app feel far more polished.
Summary
- Add a
PageStorageKeyto thekeyparameter of yourListView - If you also use
ExpansionTile, give each tile its ownPageStorageKeyas well
If you want the full sample code, you can find it at https://github.com/Pittawat2542/flutter_listview_save_scroll_position.
📚 Hope you enjoy reading!