Data Table package makes it possible to create a data table with hundreds
of rows, which is not possible using the default DataTable
widget
because of performance reasons.
- ScalableDataTable only builds the rows that are visible at each moment (similar to ListView.builder)
- Horizontal scroll if , use the
minWidth
property. - Sticky Header: The header will be visible at all times and the rows will get the rest of the available space.
Add the package to your project by running flutter pub add scalable_data_table
.
You can also add it manually in the pubspec.yaml
file.
Check the /example
folder for the example project.
class UsersTable extends StatelessWidget {
const UsersTable({Key? key}) : super(key: key);
static final _dateFormat = DateFormat('HH:mm dd/MM');
@override
Widget build(BuildContext context) {
return FutureBuilder<List<User>>(
future: createUsers(),
builder: (context, snapshot) => ScalableDataTable(
header: DefaultTextStyle(
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.grey[700],
),
child: ScalableTableHeader(
columnWrapper: columnWrapper,
children: [
const SizedBox(),
const Text('Created At'),
const Text('Name'),
const Text('Surname'),
const Text('Points'),
const Text('Interests'),
],
),
),
rowBuilder: (context, index) {
final user = snapshot.data![index];
return ScalableTableRow(
columnWrapper: columnWrapper,
color: (index % 2 == 0) ? Colors.grey[200]! : Colors.transparent,
children: [
Align(
alignment: Alignment.centerRight,
child: Text('${user.index}.'),
),
Text(_dateFormat.format(user.createdAt)),
Text(user.name),
Text(user.surname),
Text('${user.points} pts'),
Text(user.interests.join(', '), maxLines: 2),
],
);
},
emptyBuilder: (context) => const Text('No users yet...'),
itemCount: snapshot.data?.length ?? -1,
minWidth: 1000, // max(MediaQuery.of(context).size.width, 1000),
textStyle: TextStyle(color: Colors.grey[700], fontSize: 14),
),
);
}
Widget columnWrapper(BuildContext context, int columnIndex, Widget child) {
const padding = EdgeInsets.symmetric(horizontal: 10);
switch (columnIndex) {
case 0:
return Container(
width: 60,
padding: padding,
child: child,
);
case 1:
return Container(
width: 100,
padding: padding,
child: child,
);
case 5:
return Expanded(
flex: 3,
child: Container(
padding: padding,
child: child,
),
);
default:
return Expanded(
child: Container(
padding: padding,
child: child,
),
);
}
}
}