Open In App

Flutter – Preserve Scroll Position of ListView Using Page Storage

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






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.






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




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:

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


Article Tags :