Flutter PaginatedDataTable Example (with Explanations and Source Code)

In today's fast-paced world of app development, presenting data in a structured and user-friendly manner is essential. Flutter, Google's UI toolkit for building natively compiled applications for mobile, web, and desktop from a single codebase, provides a powerful widget called PaginatedDataTable that allows you to display large datasets in a paginated and organized way. In this blog post, we'll explore a comprehensive example of using the PaginatedDataTable widget in Flutter, along with explanations of its various components.

What is PaginatedDataTable?

The PaginatedDataTable widget in Flutter combines a DataTable with built-in pagination. It's a great choice when you have a large dataset that needs to be displayed in a tabular format while allowing users to navigate through different pages of the data. It provides a user-friendly interface for sorting and selecting data, making it a powerful tool for presenting complex information.

Prerequisites

Before we dive into the example, make sure you have Flutter installed and a basic understanding of the framework's concepts.

Example: Creating a PaginatedDataTable

Let's say we're developing a task management app, and we want to display a list of tasks in a paginated table format. Here's how we can achieve this using the PaginatedDataTable widget.

Step 1: Import Required Libraries

import 'package:flutter/material.dart'; 

Step 2: Create a Data Source

First, we need to define a data source that provides the data to be displayed in the table. In this example, we'll create a simple list of tasks.

class Task {
  final String name;
  final String priority;
  final DateTime dueDate;


  Task({required this.name, required this.priority, required this.dueDate});
}


class TaskDataSource extends DataTableSource {
  final List<Task> _tasks = [
    Task(name: 'Buy groceries', priority: 'High', dueDate: DateTime.now()),
    // Add more tasks here...
  ];


  @override
  DataRow? getRow(int index) {
    if (index >= _tasks.length) {
      return null;
    }
    final task = _tasks[index];
    return DataRow.byIndex(
      index: index,
      cells: [
        DataCell(Text(task.name)),
        DataCell(Text(task.priority)),
        DataCell(Text(task.dueDate.toString())),
      ],
    );
  }


  @override
  bool get isRowCountApproximate => false;


  @override
  int get rowCount => _tasks.length;


  @override
  int get selectedRowCount => 0;
}

In this data source, we've defined a Task class representing a task's name, priority, and due date. The TaskDataSource class extends DataTableSource and provides the necessary methods for the PaginatedDataTable to retrieve data.

Step 3: Create a PaginatedDataTable

Now that we have our data source ready, we can create the PaginatedDataTable widget.

class PaginatedDataTableExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Task List'),
      ),
      body: SingleChildScrollView(
        child: PaginatedDataTable(
          header: Text('Tasks'),
          columns: [
            DataColumn(label: Text('Task')),
            DataColumn(label: Text('Priority')),
            DataColumn(label: Text('Due Date')),
          ],
          source: TaskDataSource(),
          rowsPerPage: 10,
        ),
      ),
    );
  }
}

In this code snippet, we wrap the PaginatedDataTable in a SingleChildScrollView to ensure that the table fits on the screen even if the data exceeds the available space. We provide a header and column definitions using the DataColumn widget. The TaskDataSource instance is passed as the data source, and rowsPerPage determines how many rows are displayed per page.

Step 4: Run the App

To see our PaginatedDataTable in action, we need to integrate it into the app's main structure. Make sure to include the PaginatedDataTableExample widget in your app's widget tree.

void main() {
  runApp(MaterialApp(
    home: PaginatedDataTableExample(),
  ));
}

Now, when you run the app, you should see a paginated table displaying tasks with columns for task name, priority, and due date. The table will automatically handle pagination and provide a smooth user experience.

Complete Source Code

import 'package:flutter/material.dart';


void main() {
  runApp(const MyApp());
}


class MyApp extends StatelessWidget {
  const MyApp({super.key});


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FlutterforGeeks',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.green),
        useMaterial3: true,
      ),
      home: PaginatedDataTableExample(),
    );
  }
}


class PaginatedDataTableExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('FlutterforGeeks'),
      ),
      body: SingleChildScrollView(
        child: PaginatedDataTable(
          header: const Text('Tasks'),
          columns: const [
            DataColumn(label: Text('Task')),
            DataColumn(label: Text('Priority')),
            DataColumn(label: Text('Due Date')),
          ],
          source: TaskDataSource(),
          rowsPerPage: 10,
        ),
      ),
    );
  }
}


class Task {
  final String name;
  final String priority;
  final DateTime dueDate;


  Task({required this.name, required this.priority, required this.dueDate});
}


class TaskDataSource extends DataTableSource {
  final List<Task> _tasks = [
    Task(name: 'Todo1', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo2', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo3', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo4', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo5', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo6', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo7', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo8', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo9', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo10', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo11', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo12', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo13', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo14', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo15', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo16', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo17', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo18', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo19', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo20', priority: 'High', dueDate: DateTime.now()),
    Task(name: 'Todo21', priority: 'High', dueDate: DateTime.now()),


    // Add more tasks here...
  ];


  @override
  DataRow? getRow(int index) {
    if (index >= _tasks.length) {
      return null;
    }
    final task = _tasks[index];
    return DataRow.byIndex(
      index: index,
      cells: [
        DataCell(Text(task.name)),
        DataCell(Text(task.priority)),
        DataCell(Text(task.dueDate.toString())),
      ],
    );
  }


  @override
  bool get isRowCountApproximate => false;


  @override
  int get rowCount => _tasks.length;


  @override
  int get selectedRowCount => 0;
} 

Video Demo


Conclusion

The PaginatedDataTable widget in Flutter is a powerful tool for presenting and managing large datasets in a structured and user-friendly manner. By following this example and understanding its components, you can integrate paginated tables into your own Flutter applications, enhancing the way you present complex information to users. Remember to customize the example to fit your specific use case and explore additional features that the PaginatedDataTable widget offers to create even more engaging user interfaces.

Description of the image

Related Posts