Why choose davi for large data tables?

When your Flutter app needs to display thousands of rows or columns—common in admin dashboards, financial reports, or inventory management—traditional DataTable widgets can become a performance bottleneck because they render every cell at once. The davi Flutter package solves this by constructing cells only when they enter the viewport, keeping memory usage low and frame rates smooth on web and desktop platforms.

Tip: davi shines on web and desktop where virtual scrolling matters most. On mobile the performance gains are modest.

Installation

Add the package to your project with the standard Flutter command:

Code
flutter pub add davi

After the command completes, run flutter pub get to fetch the dependency.

Basic usage – a beginner‑friendly example

The following minimal app demonstrates a lazy‑loaded grid with three columns (ID, Name, Status) and 100 rows generated on the fly.

Dart / Flutter
import 'package:flutter/material.dart';
import 'package:davi/davi.dart';

void main() => runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Davi Demo',
      home: Scaffold(
        appBar: AppBar(title: const Text('Davi DataView')),
        body: Davi(
          columns: const [
            DaviColumn(name: 'ID'),
            DaviColumn(name: 'Name'),
            DaviColumn(name: 'Status'),
          ],
          source: DaviSimpleDataSource(
            rows: List.generate(100, (i) => 'Row $i'),
          ),
          cellBuilder: (context, column, row) {
            final value = row.item;
            switch (column.name) {
              case 'ID':
                return Text(row.index.toString());
              case 'Name':
                return Text(value);
              case 'Status':
                return const Icon(Icons.check, color: Colors.green);
              default:
                return const SizedBox.shrink();
            }
          },
        ),
      ),
    );
  }
}

This example uses DaviSimpleDataSource for quick prototyping. In production you’ll likely implement a custom DaviDataSource that fetches data lazily from a backend.

Customizing column width and alignment

You can control each column’s appearance via the DaviColumn properties. Below is a snippet that sets a fixed width for the ID column and right‑aligns the Status column.

Code
columns: const [
  DaviColumn(name: 'ID', width: 80, alignment: Alignment.centerRight),
  DaviColumn(name: 'Name', flex: 2), // takes remaining space proportionally
  DaviColumn(name: 'Status', width: 100, alignment: Alignment.center),
],

Performance considerations

  • Keep the cellBuilder lightweight. Heavy widgets should be extracted into separate stateless widgets and memoized if possible.
  • Avoid calling setState on the entire page when only a single cell changes. Instead, update the underlying data source and let davi rebuild the affected rows.
  • When dealing with real‑time streams, debounce rapid updates to prevent excessive rebuilds.

Remember: davi does not provide built‑in pagination. If you need page controls, implement them at the data‑source level.

Common pitfalls and how to avoid them

  • Missing data source implementation: Using DaviSimpleDataSource with static lists works for demos but does not support lazy fetching. Implement DaviDataSource for large or remote datasets.
  • Over‑complicated cell widgets: Embedding large scrollable widgets inside a cell can defeat lazy loading. Keep cells simple or use FutureBuilder inside the cell to load heavy content on demand.
  • Ignoring bidirectional scrollbars: On desktop, ensure the surrounding layout does not constrain the Davi widget’s height, otherwise vertical scrolling may be clipped.

Where to find more information

For the full API reference, configuration options, and advanced examples, visit the official package page on pub.dev:

If you encounter behavior that differs from the documentation, verify the version you are using and consult the issue tracker on the package’s GitHub repository.

FAQ

  • Q: Does davi support pagination out of the box?
    A: No. davi focuses on virtual scrolling. If you need pagination, you must implement it in your data source and trigger a refresh when the page changes.
  • Q: Can I use davi on mobile devices?
    A: Yes, the package works on mobile, but the performance advantage is most noticeable on web and desktop where large tables are common.
  • Q: How does davi handle column resizing?
    A: Column width can be set via the width or flex properties of DaviColumn. Runtime resizing UI is not provided; you would need to rebuild the widget with new column definitions.
  • Q: Is there built‑in support for sorting or filtering?
    A: The core package does not include sorting or filtering UI. You can add these features by manipulating the underlying data source and calling notifyListeners() on the source.
  • Q: Which state‑management solutions work with davi?
    A: davi is agnostic to state management. It works with Provider, Riverpod, Bloc, GetX, or any other solution as long as the data source notifies listeners of changes.

Frequently Asked Questions

Does davi support pagination out of the box?

No. davi focuses on virtual scrolling. If you need pagination, you must implement it in your data source and trigger a refresh when the page changes.

Can I use davi on mobile devices?

Yes, the package works on mobile, but the performance advantage is most noticeable on web and desktop where large tables are common.

How does davi handle column resizing?

Column width can be set via the width or flex properties of DaviColumn. Runtime resizing UI is not provided; you would need to rebuild the widget with new column definitions.

Is there built‑in support for sorting or filtering?

The core package does not include sorting or filtering UI. You can add these features by manipulating the underlying data source and calling notifyListeners() on the source.

Which state‑management solutions work with davi?

davi is agnostic to state management. It works with Provider, Riverpod, Bloc, GetX, or any other solution as long as the data source notifies listeners of changes.