Open In App

Flutter – Preserve Scroll Position of ListView Using Page Storage

Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will learn How to Preserve the Scroll Position of Listview Using Page Storage. So let’s get started.

Step By Step Implementation

Step 1: Building main.dart page

  • We have built an Appbar
  • The elevated button is used with help of which we will navigate to the next page MyList where 100 ListItems are there

Dart




import 'package:flutter/material.dart';
import 'package:preserve_scroll_position/list_Of_Items.dart';
  
void main() {
  runApp(const MyApp());
}
  
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  
    
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
          
        primarySwatch: Colors.green,
      ),
      home: const MyHomePage(),
    );
  }
}
  
class MyHomePage extends StatefulWidget {
  const MyHomePage({ Key? key }) : super(key: key);
  
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}
  
class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('GeeksForGeeks', style: TextStyle(color: Colors.white),),
        
      ), // elevated button used
      body: Center(
        child: ElevatedButton(
          onPressed: (){
            Navigator.push(context, 
            MaterialPageRoute(builder: (context)=> const MyList()),
            );  
          },
          child: Text('Page Storage Key') ),
      ),
    );
  }
}


Step2 : Building list_Of_Items.dart page

We have used ListView.builder to create 100 list items by keeping itemCount to 100.

Dart




import 'package:flutter/material.dart';
  
class MyList extends StatefulWidget {
  const MyList({Key? key}) : super(key: key);
  
  @override
  State<MyList> createState() => _MyListState();
}
  
class _MyListState extends State<MyList> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: ListView.builder(
            itemCount: 100,
            itemBuilder: (context, index) => Card(
                  child: ListTile(
                      title: Text(
                    'List Item ${index + 1}',
                    style: TextStyle(fontSize: 25),
                  )),
                )));
  }
}


Output Video:

Point of Focus

When we click the elevated button. We get navigated to the list items page where 100 list items are there. Now if we left the item page on List Item 24 and went back and again press the elevated button this list item page is getting rebuilt from the start. See the video below:

Now to fix this issue where we want to preserve the state where we left last time and when we return back the list should start from where we left earlier. For this Flutter comes with Widget called PageStorage.

What is Page Storage? 

PageStorage is used to save and restore values that can outlive the widget. For example, when multiple pages are grouped in tabs when a page is switched out, its widget is destroyed and its state is lost. By adding a PageStorage at the root and adding a PageStorageKey to each page, some of the page’s state (e.g. the scroll position of a [Scrollable] widget) will be stored automatically in its closest ancestor [PageStorage], and restored when it’s switched back. Now let’s edit the code again to see the desired result

Step 3: Implementing Pagestorage Widget in list_Of_item.dart file

  • Adding page storage key in ListView.builder
  • Wrap the ListView.builder widget with PageStorage Widget
  • Now add bucket property in PageStorage Widget which is compulsory to add
  • Now initialize the Bucket storage globally so that we can use it anywhere in the program
  • Now run the code

Dart




import 'package:flutter/material.dart';
  
// initialize bucket globally
final pageBucket = PageStorageBucket(); 
  
class MyList extends StatefulWidget {
  const MyList({Key? key}) : super(key: key);
  
  @override
  State<MyList> createState() => _MyListState();
}
  
class _MyListState extends State<MyList> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: PageStorage(
      // using page storage widget
      // bucket property used as 
      // it is mandatory
      bucket: pageBucket, 
      child: ListView.builder(
          key: PageStorageKey<String>(
              'pageOne'), //  giving key to ListView Builder
          itemCount: 100,
          itemBuilder: (context, index) => Card(
                child: ListTile(
                    title: Text(
                  'List Item ${index + 1}',
                  style: TextStyle(fontSize: 25),
                )),
              )),
    ));
  }
}


Output:

Now if you see the output:

  • We left the Items Page on ListItem 13 and clicked the back button
  • Again as we pressed the elevated button we were brought back to the ListItem 13 where we left earlier

So this is how we use PageStorage in flutter which helps to preserve the state where we left it earlier.



Last Updated : 02 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads