FlutterArtist Pagination Davi table Infinite Scroll Ex1
DAVI, short for “Data View”, is a Flutter library available on pub.dev that helps developers build complex data tables while remaining lightweight and easy to use. Davi is used in many FlutterArtist Demo examples, especially those related to displaying data tables.
FaDaviTable is a wrapper widget built around Davi, designed to simplify integration and interaction with FlutterArtist.
In this article, we will use FaDaviTable to build an infinite scrolling table. Whenever the user scrolls to the end of the table, additional data will be loaded automatically.
- FlutterArtist Davi Table (***)

- Download FlutterArtist Demo
- FlutterArtist Grid ItemsView Infinite Scroll Example
2. Country61aShelf
Country61aBlock is configured so that a maximum of 20 ITEM(s) are loaded per query.
country61a_shelf.dart
class Country61aShelf extends Shelf {
@override
ShelfStructure defineShelfStructure() {
return ShelfStructure(
filterModels: {},
blocks: [
Country61aBlock(
name: Country61aBlock.blkName,
description: null,
config: BlockConfig(
pageable: Pageable(pageSize: 20),
),
filterModelName: null,
formModel: null,
childBlocks: [],
itemSortCriteria: null,
),
],
);
}
Country61aBlock findCountry61aBlock() {
return findBlock(Country61aBlock.blkName) as Country61aBlock;
}
}3. Country61aDaviTableItemsView
When the user scrolls to the last row of the table, a Trailing widget will appear to indicate that the next set of data is being loaded.

_trailingWidget()
Widget? _trailingWidget() {
PaginationInfo? pagination = block.paginationInfo;
if (pagination == null) {
return null;
}
if (pagination.currentPage < pagination.totalPages) {
return Text("Loading...");
}
return null;
}No ADS
You need to load the next page of data inside the onTrailingWidget() callback.
Future<void> _onTrailingWidget(bool visible) async {
PaginationInfo? pagination = block.paginationInfo;
if (pagination == null) {
return;
}
if (visible && pagination.currentPage < pagination.totalPages) {
// Delay 1 second to see Trailing widget longer.
await Future.delayed(Duration(seconds: 1));
await _loadMore();
}
}Future<void> _loadMore() async {
await block.queryMore();
}Below is the complete implementation of Country61aDaviTableItemsView, demonstrating how to build an infinite scrolling data table by combining Davi, FaDaviTable, and the FlutterArtist pagination mechanism.
country61a_davi_table_items_view.dart
class Country61aDaviTableItemsView extends BlockItemsView<Country61aBlock> {
final Color? selectedColor = Colors.lightGreen.withAlpha(100);
final Color? currentColor = Colors.lightGreen;
final Color? hoverColor = Colors.greenAccent.withAlpha(30);
final formatter = NumberFormat("###,###,###", "en_US");
Country61aDaviTableItemsView({
required super.block,
super.key,
});
//
// Davi Tutorials:
// https://caduandrade.github.io/davi_flutter_demo/
//
@override
Widget buildContent(BuildContext context) {
return Container(
padding: EdgeInsets.only(right: 0),
child: DaviTheme(
data: _daviThemeData(),
child: FaDaviTable<String, CountryInfo>(
items: block.items,
getItemId: block.getItemId,
sortRuleSide: SortRuleSide.blockSide,
modelSettings: FaDaviTableModelSettings<CountryInfo>(
ignoreDataComparators: true,
sortingMode: SortingMode.disabled,
columns: [
DaviColumn(
name: 'Image',
resizable: false,
width: 60,
cellWidget: (param) {
return Center(
child: ImageUrlView(
imageUrl: param.data.imageUrl,
size: 30,
boxShape: BoxShape.rectangle,
),
);
},
),
DaviColumn(
name: 'Name In English',
grow: 1,
cellValue: (param) {
return param.data.nameInEnglish;
},
),
DaviColumn(
name: 'Population',
width: 100,
cellAlignment: Alignment.centerRight,
cellValue: (param) {
return param.data.population;
},
cellValueStringify: _formatNumber,
),
DaviColumn(
name: 'Area (Km2)',
width: 100,
cellAlignment: Alignment.centerRight,
cellValue: (param) {
return param.data.area;
},
cellValueStringify: _formatNumber,
),
],
),
visibleRowsCount: 10,
// IMPORTANT: For Infinite Scroll Pagination.
trailingWidget: _trailingWidget(),
// IMPORTANT: For Infinite Scroll Pagination.
onTrailingWidget: _onTrailingWidget,
onRowTap: (CountryInfo countryInfo) {
_setCountryAsCurrent(countryInfo);
},
rowColor: (param) {
CountryInfo item = param.data;
bool selected = block.isSelectedItem(item);
bool current = block.isCurrentItem(item);
if (current) {
return currentColor;
} else if (selected) {
return selectedColor;
}
return null;
},
),
),
);
}
Widget? _trailingWidget() {
PaginationInfo? pagination = block.paginationInfo;
if (pagination == null) {
return null;
}
if (pagination.currentPage < pagination.totalPages) {
return Text("Loading...");
}
return null;
}
Future<void> _onTrailingWidget(bool visible) async {
PaginationInfo? pagination = block.paginationInfo;
if (pagination == null) {
return;
}
if (visible && pagination.currentPage < pagination.totalPages) {
// Delay 1 second to see Trailing widget longer.
await Future.delayed(Duration(seconds: 1));
await _loadMore();
}
}
Future<void> _loadMore() async {
await block.queryMore();
}
String _formatNumber(dynamic value) {
return formatter.format(value);
}
DaviThemeData _daviThemeData() {
return DaviThemeData(
columnDividerThickness: 0.4,
columnDividerFillHeight: true,
decoration: BoxDecoration(
border: Border.all(
width: 0.2,
color: Colors.grey,
),
),
scrollbar: TableScrollbarThemeData(
horizontalOnlyWhenNeeded: true,
verticalOnlyWhenNeeded: true,
),
header: HeaderThemeData(),
headerCell: HeaderCellThemeData(
padding: EdgeInsets.all(5),
height: 30,
),
row: RowThemeData(
dividerThickness: 0.4,
fillHeight: true,
color: null,
hoverBackground: (int row) {
if (block.isCurrentIndex(row)) {
return currentColor;
} else if (block.isSelectedIndex(row)) {
return selectedColor;
} else {
return hoverColor;
}
},
),
cell: CellThemeData(
padding: EdgeInsets.all(5),
contentHeight: 30,
),
);
}
Future<void> _setCountryAsCurrent(CountryInfo countryInfo) async {
FlutterArtist.codeFlowLogger.addMethodCall(
ownerClassInstance: this,
currentStackTrace: StackTrace.current,
parameters: {"countryInfo": countryInfo},
);
//
await block.refreshItemAndSetAsCurrent(
item: countryInfo,
);
}
}No ADS
FlutterArtist
- Basic concepts in Flutter Artist
- FlutterArtist Block ex1
- FlutterArtist Form ex1
- FlutterArtist FormModel.patchFormFields() Ex1
- FlutterArtist BlockQuickItemUpdateAction Ex1
- FlutterArtist BlockNumberPagination Ex1
- FlutterArtist BlockQuickMultiItemCreationAction Ex1
- FlutterArtist ListView Infinite Scroll Pagination Example
- FlutterArtist Pagination
- FlutterArtist Sort DropdownSortPanel Example
- FlutterArtist BackgroundWebDownloadAction ex1
- FlutterArtist Master-detail Blocks ex1
- FlutterArtist Scalar ex1
- FlutterArtist Pagination Davi table Infinite Scroll Ex1
- FlutterArtist Form Parent-child MultiOptFormProp ex1
- FlutterArtist Context Provider Views
- FlutterArtist Internal Shelf Event ex1
Show More

