flutter_pagination_widget

pub package License: MIT

A lightweight, responsive, overflow-proof, and fully customizable pagination widget for Flutter. Easily integrate modern pagination controls into your mobile, web, or desktop applications without relying on external dependencies.


✨ Features

  • 📱 Cross-Platform: Mobile, Web, and Desktop ready.
  • 🧮 Smart Pagination Model: Calculate page ranges (from, to, lastPage) automatically via PaginationModel.calculate().
  • 🔢 Rows Per Page Selector: Optional dropdown selector (e.g. 10, 20, 50, 100) with onPageSizeChanged callback.
  • 🚀 Direct Jump to Page: Sleek inline page input field with automatic out-of-bounds page clamping and keyboard dismissal.
  • ⏭️ First & Last Page Navigation: Quick navigation controls (firstPageChild, lastPageChild).
  • 📐 Adaptive Layouts: Four layout modes (PaginationLayoutMode.auto, row, wrap, column) to prevent UI overflows on narrow screens.
  • 🎨 Rich Customization: Custom colors, borders, padding, font styles, and custom item builders (pageButtonBuilder, infoTextBuilder).
  • 📦 Zero External Dependencies: 100% Dart & Flutter.

💻 Installation

Add flutter_pagination_widget to your pubspec.yaml:

dependencies:
  flutter_pagination_widget: ^0.1.0

Then run:

flutter pub get

🚀 Usage

1. Simple Usage with PaginationModel.calculate

Use PaginationModel.calculate to automatically compute entry bounds and total pages based on your total item count and page size:

import 'package:flutter/material.dart';
import 'package:flutter_pagination_widget/flutter_pagination_widget.dart';

class SimplePaginationExample extends StatefulWidget {
  const SimplePaginationExample({super.key});

  @override
  State<SimplePaginationExample> createState() => _SimplePaginationExampleState();
}

class _SimplePaginationExampleState extends State<SimplePaginationExample> {
  int currentPage = 1;
  int pageSize = 10;
  final int totalItems = 125;

  @override
  Widget build(BuildContext context) {
    // Automatically calculates 'from', 'to', and 'lastPage'
    final meta = PaginationModel.calculate(
      total: totalItems,
      currentPage: currentPage,
      pageSize: pageSize,
    );

    return Scaffold(
      body: Center(
        child: PaginationWidget(
          meta: meta,
          onPageChanged: (page) => setState(() => currentPage = page),
          onPageSizeChanged: (newSize) {
            setState(() {
              pageSize = newSize;
              currentPage = 1; // Reset to page 1 when page size changes
            });
          },
          showFirstLastButtons: true,
          showPageSizeSelector: true,
          showJumpToPage: true,
          pageSizeOptions: const [10, 20, 50, 100],
          primaryColor: Colors.teal,
        ),
      ),
    );
  }
}

2. Advanced Customization & Builders

PaginationWidget(
  meta: meta,
  onPageChanged: (page) => setState(() => currentPage = page),
  
  // Feature Toggles
  showInfoText: true,
  showFirstLastButtons: true,
  showPageSizeSelector: true,
  showJumpToPage: true,

  // Layout Mode & Page Range
  layoutMode: PaginationLayoutMode.auto,
  visiblePagesCount: 2,

  // Custom Colors & Styles
  primaryColor: Colors.deepPurple,
  activeBackgroundColor: Colors.deepPurple,
  activeTextColor: Colors.white,
  inactiveBackgroundColor: Colors.grey.shade100,
  disabledBackgroundColor: Colors.grey.shade100,
  disabledTextColor: Colors.grey.shade400,
  borderColor: Colors.deepPurple.shade100,
  borderRadius: BorderRadius.circular(10),
  buttonPadding: 10.0,

  // Custom Text Formatters
  infoTextBuilder: (from, to, total) => 'Displaying $from - $to of $total items',
  pageSizeLabel: 'Items per page:',
  jumpToPageLabel: 'Go to:',

  // Custom Item Builder
  pageButtonBuilder: (context, page, isSelected, onTap) {
    return GestureDetector(
      onTap: onTap,
      child: Container(
        margin: const EdgeInsets.symmetric(horizontal: 4),
        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
        decoration: BoxDecoration(
          color: isSelected ? Colors.deepPurple : Colors.transparent,
          borderRadius: BorderRadius.circular(20),
          border: Border.all(color: Colors.deepPurple),
        ),
        child: Text(
          '$page',
          style: TextStyle(
            color: isSelected ? Colors.white : Colors.deepPurple,
            fontWeight: FontWeight.bold,
          ),
        ),
      ),
    );
  },
)

🛠️ API Reference

PaginationWidget Properties

Parameter Type Default Description
meta PaginationModel required Holds pagination state (from, to, total, currentPage, lastPage, pageSize).
onPageChanged ValueChanged<int> required Callback when a user selects or jumps to a page.
onPageSizeChanged ValueChanged<int>? null Callback triggered when user selects a different page size from dropdown.
showInfoText bool true Shows or hides the entry info text ("Showing X to Y of Z entries").
showFirstLastButtons bool false Shows or hides First (<<) and Last (>>) page navigation buttons.
showPageSizeSelector bool false Enables or disables the items-per-page dropdown selector.
showJumpToPage bool false Enables or disables the direct page jump input box.
layoutMode PaginationLayoutMode auto Configures layout style: auto, row, wrap, or column.
visiblePagesCount int 1 Number of adjacent page buttons to show around the current page.
primaryColor Color Colors.blue Primary theme color for active buttons & borders.
textColor Color Colors.black87 Default text color.
activeBackgroundColor Color? primaryColor Background color of selected page button.
activeTextColor Color? Colors.white Text color of selected page button.
borderRadius BorderRadius? BorderRadius.circular(4) Border radius for buttons and input containers.
infoTextBuilder Function(from, to, total)? null Custom formatter function for info text.
pageButtonBuilder Function(context, page, isSelected, onTap)? null Custom builder widget for page number buttons.

PaginationModel Properties

Property Type Description
PaginationModel.calculate() Factory Helper constructor that automatically computes from, to, and lastPage.
from int Starting entry index (1-based).
to int Ending entry index.
total int Total count of entries across all pages.
currentPage int Currently active page number.
lastPage int Total number of pages.
pageSize int Number of items displayed per page.
hasNext bool Getter indicating if a next page exists.
hasPrevious bool Getter indicating if a previous page exists.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.