ResponsiveTable class

A responsive table that automatically switches between:

  • A full data table on desktop/tablet screens
  • A list of cards on mobile/watch screens

Performance Design

  • Uses ListView.builder for lazy card rendering on mobile (O(visible) not O(n))
  • Desktop table uses DataTable which Flutter handles efficiently
  • Single ScreenType check per build — O(1) mode selection
  • RepaintBoundary wraps card items for isolated repaints

Example

ResponsiveTable(
  columns: ['Name', 'Price', 'Status', 'Date'],
  rows: products.map((p) => [p.name, p.price, p.status, p.date]).toList(),
  mobileCardBuilder: (context, row, headers) => Card(
    child: ListTile(
      title: Text(row[0].toString()),
      subtitle: Text(row[1].toString()),
    ),
  ),
  hiddenColumnsOnMobile: [3],
)
Inheritance

Constructors

ResponsiveTable({Key? key, required List<String> columns, required List<List> rows, Widget mobileCardBuilder(BuildContext context, List row, List<String> headers)?, List<int>? hiddenColumnsOnMobile, void onRowTap(int index, List row)?, ScreenType tableBreakpoint = ScreenType.mobile, bool showSortIndicator = false, int? sortColumnIndex, bool sortAscending = true, void onSort(int columnIndex, bool ascending)?, Widget? tableHeading, EdgeInsetsGeometry cardListPadding = const EdgeInsets.all(8), double cardSpacing = 8.0, bool horizontalScroll = true, Decoration? tableDecoration, bool cardShrinkWrap = true, ScrollPhysics? cardPhysics})
Creates a ResponsiveTable.
const

Properties

cardListPadding → EdgeInsetsGeometry
Padding for the mobile card list. Default: EdgeInsets.all(8).
final
cardPhysics → ScrollPhysics?
Scroll physics for the mobile card list.
final
cardShrinkWrap → bool
Whether the mobile card list should shrink-wrap its content.
final
cardSpacing → double
Spacing between mobile cards (scaled via .s). Default: 8.0.
final
columns → List<String>
Column headers for the table.
final
hashCode → int
The hash code for this object.
no setterinherited
hiddenColumnsOnMobile → List<int>?
Column indices to hide on mobile screens (0-indexed). These columns are excluded from both the default card and from the mobileCardBuilder's provided data.
final
horizontalScroll → bool
Whether the table should have horizontal scroll on desktop when columns overflow. Default: true.
final
key → Key?
Controls how one widget replaces another widget in the tree.
finalinherited
mobileCardBuilder → Widget Function(BuildContext context, List row, List<String> headers)?
Optional builder for mobile card representation. Receives the row data and column headers. If null, a default card layout is used.
final
onRowTap → void Function(int index, List row)?
Optional callback when a row is tapped.
final
onSort → void Function(int columnIndex, bool ascending)?
Callback when a column header is tapped for sorting.
final
rows → List<List>
Row data — each inner list corresponds to one row. Values can be any type; they are converted to String for display.
final
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
showSortIndicator → bool
Whether to show column sort indicators. Default: false.
final
sortAscending → bool
Whether the current sort is ascending.
final
sortColumnIndex → int?
The currently sorted column index. Used with showSortIndicator.
final
tableBreakpoint → ScreenType
The ScreenType at which to switch from cards to table. Default: ScreenType.mobile (table starts at tablet).
final
tableDecoration → Decoration?
Decoration for the data table (desktop/tablet).
final
tableHeading → Widget?
Optional heading for the data table.
final

Methods

build(BuildContext context) → Widget
Describes the part of the user interface represented by this widget.
override
createElement() → StatelessElement
Creates a StatelessElement to manage this widget's location in the tree.
inherited
debugDescribeChildren() → List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep.
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) → String
A string representation of this object.
inherited
toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) → String
Returns a string representation of this node and its descendants.
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String
Returns a one-line detailed description of the object.
inherited
toStringShort() → String
A short, textual description of this widget.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited