Flutter Table Widget
The Flutter Table widget arranges widgets in rows and columns. It is useful when each row has the same number of cells and the content needs aligned column boundaries, such as comparison grids, schedules, dashboards, and small forms.
A Table is not a scrolling data-grid widget. Every cell is laid out as part of the widget tree, so for large or dynamic datasets, a lazily built widget such as ListView is usually more suitable. For Material-style tabular data with headings, sorting, and selectable rows, consider DataTable.
Flutter Table Basic Syntax
Create a table by supplying a list of TableRow objects to the children property. Each row should normally contain the same number of child widgets.
Table(
children: [
TableRow(
children: [
WidgetA(),
WidgetB(),
],
),
TableRow(
children: [
WidgetC(),
WidgetD(),
],
),
],
)
Flutter Table Properties for Layout and Styling
children: Defines the table rows as a list ofTableRowobjects.border: Draws borders around the table and its cells usingTableBorder.columnWidths: Assigns aTableColumnWidthstrategy to selected column indexes.defaultColumnWidth: Sets the width strategy for columns not listed incolumnWidths.defaultVerticalAlignment: Controls vertical alignment for cells that do not specify their own alignment.textDirection: Determines the order in which columns are laid out.textBaseline: Supplies the baseline used when baseline alignment is selected.
Common column-width strategies include FlexColumnWidth, FractionColumnWidth, FixedColumnWidth, IntrinsicColumnWidth, MinColumnWidth, and MaxColumnWidth. Choose a strategy based on whether a column should share available space, use a percentage, keep a fixed size, or follow its content.
Flutter Table Example with Icons and Borders
In this example Flutter Application, we shall display some Icons and Row widgets in a table layout.
main.dart
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
double iconSize = 40;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Table - tutorialkart.com'),
),
body: Center(
child: Column(children: <Widget>[
Container(
margin: EdgeInsets.all(10),
child: Table(
border: TableBorder.all(),
children: [
TableRow( children: [
Column(children:[
Icon(Icons.account_box, size: iconSize,),
Text('My Account')
]),
Column(children:[
Icon(Icons.settings, size: iconSize,),
Text('Settings')
]),
Column(children:[
Icon(Icons.lightbulb_outline, size: iconSize,),
Text('Ideas')
]),
]),
TableRow( children: [
Icon(Icons.cake, size: iconSize,),
Icon(Icons.voice_chat, size: iconSize,),
Icon(Icons.add_location, size: iconSize,),
]),
],
),
),
]))),
);
}
}
Run this application in an Android Emulator and you may get an UI as shown below. If you notice, we have mentioned the border for Table widget, hence border is displayed. You can remove the property to not display the border.

TableBorder.all() applies a border around every cell. You can also create a custom TableBorder to style the outer edges and internal dividers separately.
Flutter Table with Different Column Widths
You can specify different column widths. In this example, we display the same items that we used in the previous example, in a table layout, but with different widths.
main.dart
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
double iconSize = 40;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Table - tutorialkart.com'),
),
body: Center(
child: Column(children: <Widget>[
Container(
margin: EdgeInsets.all(10),
child: Table(
border: TableBorder.all(),
columnWidths: {0: FractionColumnWidth(.4), 1: FractionColumnWidth(.2), 2: FractionColumnWidth(.4)},
children: [
TableRow( children: [
Column(children:[
Icon(Icons.account_box, size: iconSize,),
Text('My Account')
]),
Column(children:[
Icon(Icons.settings, size: iconSize,),
Text('Settings')
]),
Column(children:[
Icon(Icons.lightbulb_outline, size: iconSize,),
Text('Ideas')
]),
]),
TableRow( children: [
Icon(Icons.cake, size: iconSize,),
Icon(Icons.voice_chat, size: iconSize,),
Icon(Icons.add_location, size: iconSize,),
]),
],
),
),
]))),
);
}
}
Run this application, and you may get an UI as shown below, with first and third columns taking 40% width each and second column taking 20%.

The keys in columnWidths are zero-based column indexes. In this example, column 0 and column 2 each use 40% of the table width, while column 1 uses 20%. Fraction values should normally add up to 1.0 when the columns are intended to fill the complete width.
Add Padding and Alignment to Flutter Table Cells
The Table widget does not provide a single cell-padding property. Wrap each cell in Padding, Container, or Align when you need spacing, background decoration, or horizontal alignment.
Table(
border: TableBorder.all(),
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
children: [
TableRow(
children: [
Padding(
padding: const EdgeInsets.all(12),
child: Text('Name'),
),
Padding(
padding: const EdgeInsets.all(12),
child: Text('Status'),
),
],
),
TableRow(
children: [
Padding(
padding: const EdgeInsets.all(12),
child: Text('Account'),
),
Padding(
padding: const EdgeInsets.all(12),
child: Align(
alignment: Alignment.center,
child: Text('Active'),
),
),
],
),
],
)
defaultVerticalAlignment applies to all cells unless a cell is wrapped in TableCell with a different verticalAlignment. Baseline alignment is mainly useful for text and requires a matching textBaseline.
Prevent Flutter Table Overflow on Narrow Screens
A table can overflow horizontally when fixed-width columns or wide cell content exceed the available screen width. Prefer flexible or fractional widths for responsive layouts. When the table must remain wider than the viewport, place it inside a horizontal SingleChildScrollView.
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SizedBox(
width: 600,
child: Table(
border: TableBorder.all(),
children: rows,
),
),
)
Wrapping the table in a scroll view solves horizontal viewport overflow, but it does not make row creation lazy. Avoid building a very large number of rows with Table.
Flutter Table, DataTable, and ListView Differences
| Widget | Use it when |
|---|---|
Table | You need a custom grid made from arbitrary widgets, with full control over rows, columns, borders, and widths. |
DataTable | You need a Material-style data table with column labels and structured data rows. |
ListView | You need a long, scrollable, lazily built collection where strict column alignment is not required. |
Flutter Table Common Questions
How do I set equal column widths in a Flutter Table?
Use FlexColumnWidth() for the columns, or rely on the default flexible column width when no custom widths are supplied. Columns with the same flex value share the available width equally.
How do I add spacing inside Flutter Table cells?
Wrap each cell widget with Padding or a Container that has a padding value. The Table widget itself has no general cell-padding property.
Can a Flutter Table scroll?
Table does not scroll by itself. Wrap it in SingleChildScrollView for horizontal or vertical scrolling. For many rows, use a lazy scrolling widget instead of building the entire table at once.
Why does a Flutter Table overflow?
Overflow occurs when the combined column widths or cell contents are wider than the available constraints. Use flexible widths, allow text to wrap, reduce fixed dimensions, or provide horizontal scrolling.
Flutter Table Tutorial Summary
In this Flutter Tutorial, we learned how to display widgets in rows and columns using the Table widget, draw cell borders, assign different column widths, add padding and alignment, and handle narrow-screen overflow.
TutorialKart.com