Implement Effective Pagination in the Flutter ListView in Just 4 Steps!
Tags: flutter, mobile, android, ios
Published: 2021-01-05 03:54:08

---
title: Implement Effective Pagination in the Flutter ListView in Just 4 Steps!
published: true
date: 2020-12-30 13:01:21 UTC
tags: flutter, mobile, android, ios
canonical_url: https://www.syncfusion.com/blogs/post/implement-effective-pagination-in-the-flutter-listview-in-just-4-steps.aspx
cover_image: https://www.syncfusion.com/blogs/wp-content/uploads/2020/12/Implement-Effective-Pagination-in-the-Flutter-ListView-in-Just-4-Steps-672x372.png
---

Paging is an essential feature that helps us effectively load large volumes of data. Our Syncfusion [Flutter DataPager widget](https://help.syncfusion.com/flutter/datagrid/paging) provides built-in options to page data on demand. It can be placed at either the top or bottom of the page.

In our previous blog, we learned the steps to [integrate the DataPager with the Syncfusion Flutter DataGrid](https://dev.to/karthickramasamy08/introducing-pagination-in-the-syncfusion-flutter-datagrid-109p-temp-slug-9890682). In this blog, we are going to discuss how to integrate the [DataPager](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataPager-class.html) with the Flutter [ListView](https://api.flutter.dev/flutter/widgets/ListView-class.html) to replicate a simple online shopping app to order fruit.

**Note:**  In this blog, we use static data for the examples, not data from the web.

Let’s get started!

## Steps to integrate DataPager with a Flutter ListView

Please follow the four simple steps given in this blog to enable pagination in the Flutter ListView with our Syncfusion DataPager.

### Step 1:

Include the Syncfusion Flutter DataGrid package dependency in the **pubspec.yaml** file of your project with the following code.

```cmd
syncfusion_flutter_datagrid: ^18.4.30-beta
```

### Step 2:

Import the DataGrid package in the **main.dart** file using the following code example.

```dart
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:syncfusion_flutter_core/theme.dart';
```

### Step: 3

1. Create a common delegate for both the DataPager and ListView **.** 
2. Extend the [SliverChildBuilderDelegate](https://api.flutter.dev/flutter/widgets/SliverChildBuilderDelegate-class.html) with the [DataPagerDelegate](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/DataPagerDelegate-class.html) and [ChangeNotifier](https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html) to notify the DataPager to refresh the pager when a CRUD operation is performed.
3. Override the **childCount** property from the **SliverChildBuilderDelegate** to set the defined length for the child.
4. Override the **rowCount** property from the **DataPagerDelegate** and set the total length of the data source.
5. Now, override the **handlePageChange** method to segment the data and load the segmented data to the data pager. Then, the **handlePageChange** method will be called for every navigation between the pages.

Refer to the following code example.

```dart
class CustomSliverChildBuilderDelegate extends SliverChildBuilderDelegate
    with DataPagerDelegate, ChangeNotifier {
  CustomSliverChildBuilderDelegate(builder) : super(builder);

  @override
  int get childCount => _paginatedProductData.length;

  @override
  int get rowCount => _products.length;

  @override
  Future<bool> handlePageChange(int oldPageIndex, int newPageIndex,
      int startRowIndex, int rowsPerPage) async {
    int endIndex = startRowIndex + rowsPerPage;

    if (endIndex > _products.length) {
      endIndex = _products.length - 1;
    }

    await Future.delayed(Duration(milliseconds: 2000));
    _paginatedProductData = _products
        .getRange(startRowIndex, endIndex)
        .toList(growable: false);

    notifyListeners();
    return true;
  }

  @override
  bool shouldRebuild(covariant CustomSliverChildBuilderDelegate oldDelegate) {
    return true;
  }
}
```

### Step 4:

Finally, create an instance of the **CustomSliverChildBuilderDelegate** and assign that to both the ListView’s [childrenDelegate](https://api.flutter.dev/flutter/widgets/ListView/childrenDelegate.html) and the DataPager’s [delegate](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataPager/delegate.html) properties.

Refer to the following code example.

```dart
List<PagingProduct> _paginatedProductData = [];

List<PagingProduct> _products = [];

bool showLoadingIndicator = false;

static const double dataPagerHeight = 70.0;

@override
void initState() {
  super.initState();
  _products = List.from(populateData());
}

void rebuildList() {
  setState(() {});
}

Widget loadListView(BoxConstraints constraints) {
  List<Widget> _getChildren() {
    final List<Widget> stackChildren = [];

    if (_products.isNotEmpty) {
      stackChildren.add(ListView.custom(
          childrenDelegate: CustomSliverChildBuilderDelegate(indexBuilder)));
    }

    if (showLoadingIndicator) {
      stackChildren.add(Container(
        color: Colors.black12,
        width: constraints.maxWidth,
        height: constraints.maxHeight,
        child: Align(
          alignment: Alignment.center,
          child: CircularProgressIndicator(
            strokeWidth: 3,
          ),
        ),
      ));
    }
    return stackChildren;
  }

  return Stack(
    children: _getChildren(),
  );
}

@override
Widget build(BuildContext context) {
  return MaterialApp(
    theme: ThemeData(
      primarySwatch: Colors.blue,
      visualDensity: VisualDensity.adaptivePlatformDensity,
    ),
    home: Scaffold(
      appBar: AppBar(
        title: Text('Fruits'),
      ),
      body: LayoutBuilder(builder: (context, constraint) {
        return Column(
          children: [
            Container(
              height: constraint.maxHeight - dataPagerHeight,
              child: loadListView(constraint),
            ),
            Container(
              height: dataPagerHeight,
              child: SfDataPagerTheme(
                  data: SfDataPagerThemeData(
                    itemBorderRadius: BorderRadius.circular(5),
                  ),
                  child: SfDataPager(
                      rowsPerPage: 10,
                     onPageNavigationStart: (pageIndex) {
                         setState(() {
                            showLoadingIndicator = true;
                         });
                       },
                      onPageNavigationEnd: (pageIndex) {
                        setState(() {
                          showLoadingIndicator = false;
                        });
                       },
                      delegate: CustomSliverChildBuilderDelegate(indexBuilder)
                        ..addListener(rebuildList))),
            )
          ],
        );
      }),
    ),
  );
}

Widget indexBuilder(BuildContext context, int index) {
  final PagingProduct data = _paginatedProductData[index];
  return ListTile(
    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
    title: LayoutBuilder(
      builder: (context, constraint) {
        return Container(
            width: constraint.maxWidth,
            height: 100,
            child: Row(
              children: [
                Align(
                  alignment: Alignment.centerRight,
                  child: Container(
                    clipBehavior: Clip.antiAlias,
                    decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(10)),
                    child: Image.asset(data.image, width: 100, height: 100),
                  ),
                ),
                Container(
                  padding: EdgeInsets.fromLTRB(20, 10, 5, 5),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: [
                      Container(
                        width: constraint.maxWidth - 130,
                        child: Text(data.name,
                            style: TextStyle(
                                fontWeight: FontWeight.w600,
                                color: Colors.black87,
                                fontSize: 15)),
                      ),
                      Container(
                        width: constraint.maxWidth - 130,
                        child: Text(data.weight,
                            style: TextStyle(
                                color: Colors.black87, fontSize: 10)),
                      ),
                      Container(
                        width: constraint.maxWidth - 130,
                        child: Row(
                          children: [
                            Container(
                              color: Colors.green.shade900,
                              padding: EdgeInsets.all(3),
                              child: Row(
                                children: [
                                  Text('${data.reviewValue}',
                                      textAlign: TextAlign.end,
                                      style: TextStyle(
                                          color: Colors.white, fontSize: 13)),
                                  SizedBox(width: 2),
                                  Icon(
                                    Icons.star,
                                    color: Colors.white,
                                    size: 15,
                                  )
                                ],
                              ),
                            ),
                            SizedBox(width: 5),
                            Text('${data.ratings}',
                                textAlign: TextAlign.end,
                                style: TextStyle(
                                    color: Colors.black87, fontSize: 11))
                          ],
                        ),
                      ),
                      Container(
                        width: constraint.maxWidth - 130,
                        child: Row(
                          children: [
                            Container(
                              child: Text('\$${data.price}',
                                  style: TextStyle(
                                      color: Colors.green.shade800,
                                      fontSize: 13)),
                            ),
                            SizedBox(width: 8),
                            Text('${data.offer}',
                                style: TextStyle(
                                    color: Colors.black87, fontSize: 10))
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ));
      },
    ),
  );
}
```

After executing the previous code example,  we will get output like in the following GIF image.

![Pagination feature in Flutter ListView](https://www.syncfusion.com/blogs/wp-content/uploads/2020/12/Pagination-feature-in-ListView.gif)<figcaption>Pagination feature in Flutter ListView</figcaption>

## GitHub reference

You can get the complete source code for the example used in this blog in this [GitHub repository](https://github.com/SyncfusionExamples/how-to-apply-paging-in-flutter-listview-using-sfdatapager).

## Conclusion

In this blog, we have covered how to integrate the Syncfusion Flutter [DataPager widget](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataPager-class.html) with the [Flutter ListView](https://api.flutter.dev/flutter/widgets/ListView-class.html) widget to replicate a fruit ordering app. Follow these four simple steps and you will definitely say, “This is easy!”

The [Syncfusion Flutter](https://www.syncfusion.com/flutter-widgets) suite offers fast, fluid, and flexible widgets for creating high-quality apps for iOS, Android, and the web. Use them to build beautiful applications!

For existing customers, the new version is available for download from the [License and Downloads](https://www.syncfusion.com/account/downloads) page. If you are not yet a Syncfusion customer, you can try our 30-day [free trial](https://www.syncfusion.com/downloads) to check out our available features. Also, try our samples from this [GitHub](https://github.com/syncfusion/flutter-examples) location.

You can also reach us through our[ support forums](https://www.syncfusion.com/forums), [Direct-Trac](https://www.syncfusion.com/support/directtrac/incidents), or [feedback portal](https://www.syncfusion.com/feedback/flutter). We are always happy to assist you!