The Syncfusion Flutter DataGrid (data table) widget provides support to load data lazily with an interactive view when the grid reaches its maximum offset while scrolling down. In this blog, we are going to discuss how to enable the load-more feature in Flutter DataGrid and perform the lazy loading of data fetched from Firebase. Before getting into the steps, go through the overview of connecting Firebase to your Flutter application.
Note: In this blog, we use Firebase data as an example only. We are not going to provide the Firebase connectivity files here.
Include the Syncfusion Flutter DataGrid and Firebase package dependencies in the pubspec.yaml file of your project using the following code.
firebase_core: ^1.0.2 cloud_firestore: ^1.0.3 syncfusion_flutter_datagrid: ^19.1.54-beta.1
Create an employee class to cast and store the Firebase data in your project.
Refer to the following code example.
import 'package:cloud_firestore/cloud_firestore.dart'; class Employee { Employee(this.employeeID, this.employeeName, this.designation, this.salary, {this.reference}); double employeeID; String employeeName; String designation; double salary; DocumentReference? reference; factory Employee.fromSnapshot(DocumentSnapshot snapshot) { Employee newEmployee = Employee.fromJson(snapshot.data()!); newEmployee.reference = snapshot.reference; return newEmployee; } factory Employee.fromJson(Map<String, dynamic> json) => _employeeFromJson(json); Map<String, dynamic> toJson() => _employeeToJson(this); @override String toString() => 'employeeName $employeeName'; } Employee _employeeFromJson(Map<String, dynamic> data) { return Employee( data['employeeID'], data['employeeName'], data['designation'], data['salary'], ); } Map<String, dynamic> _employeeToJson(Employee instance) { return { 'employeeID' : instance.employeeID, 'employeeName': instance.employeeName, 'designation': instance.designation, 'salary': instance.salary, }; }
Please follow these steps to create a DataGridSource and initialize the Firebase:
First, create a DataGridSource class, which is required for the SfDataGrid. With this class, we are going to obtain the row data.
import 'dart:async'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:syncfusion_flutter_datagrid/datagrid.dart'; import '../model/employee.dart'; class EmployeeDataGridSource extends DataGridSource { List<DataGridRow> dataGridRows = []; List<Employee> employees = []; @override List<DataGridRow> get rows => dataGridRows; @override DataGridRowAdapter? buildRow(DataGridRow row) { return DataGridRowAdapter( cells: row.getCells().map<Widget>((dataGridCell) { if (dataGridCell.columnName == 'employeeID' || dataGridCell.columnName == 'salary') { return Container( alignment: Alignment.centerRight, padding: EdgeInsets.symmetric(horizontal: 16.0), child: Text( (dataGridCell.columnName == 'salary') ? NumberFormat.currency(locale: 'en_US', symbol: '\
Then, we have to initialize Firebase in the main() method to access the Firebase services.
import 'package:firebase_core/firebase_core.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); runApp(SfDataGridLoadMoreApp()); }
Now, initialize the Firebase collection inside the DataGridSource class to fetch data from the cloud.
import 'package:cloud_firestore/cloud_firestore.dart'; class EmployeeDataGridSource extends DataGridSource { EmployeeDataGridSource() { collection = FirebaseFirestore.instance.collection('employees'); } late CollectionReference collection; }
Now, let’s enable the lazy-loading feature in the Flutter DataGrid:
First, import the Flutter DataGrid and Firebase repository packages in the main.dart file using the following code.
import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_datagrid_loadmore/repositories/employee_repository.dart'; import 'package:syncfusion_flutter_datagrid/datagrid.dart';
We can perform lazy loading by using either of the following ways in the Flutter data table:
In this blog, we are going to lazy load data using the infinite-scrolling feature in the DataGrid:
Refer to the following code example.
import 'dart:async'; import 'package:flutter/material.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter_datagrid_loadmore/repositories/employee_repository.dart'; import 'package:syncfusion_flutter_datagrid/datagrid.dart'; class SfDataGridLoadMoreApp extends StatelessWidget { final EmployeeDataGridSource employeeDataGridSource = EmployeeDataGridSource(); SfDataGridLoadMoreApp() { employeeDataGridSource.loadMoreStream(); } @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: Scaffold( appBar: AppBar( title: Text('DataGrid Lazy Loading'), ), body: SfDataGrid( source: employeeDataGridSource, columnWidthMode: ColumnWidthMode.fill, columns: [ GridTextColumn( columnName: 'employeeID', label: Container( padding: EdgeInsets.symmetric(horizontal: 16.0), child: Text( 'ID', overflow: TextOverflow.ellipsis, ), alignment: Alignment.centerRight, )), GridTextColumn( columnName: 'employeeName', label: Container( padding: EdgeInsets.symmetric(horizontal: 16.0), child: Text( 'Name', overflow: TextOverflow.ellipsis, ), alignment: Alignment.centerLeft)), GridTextColumn( columnName: 'designation', label: Container( padding: EdgeInsets.symmetric(horizontal: 16.0), child: Text( 'Role', overflow: TextOverflow.ellipsis, ), alignment: Alignment.centerLeft)), GridTextColumn( columnName: 'salary', label: Container( padding: EdgeInsets.symmetric(horizontal: 16.0), child: Text( 'Salary', overflow: TextOverflow.ellipsis, ), alignment: Alignment.centerRight)), ], loadMoreViewBuilder: loadMoreInfiniteBuilder, ), ), ); } /// Hook this builder for applying the infinite scrolling support Widget loadMoreInfiniteBuilder( BuildContext context, LoadMoreRows loadMoreRows) { Future<String> loadRows() async { await loadMoreRows(); return Future<String>.value('Completed'); } return FutureBuilder<String>( initialData: 'loading', future: loadRows(), builder: (context, snapShot) { if (snapShot.data == 'loading') { return Container( height: 60.0, width: double.infinity, decoration: BoxDecoration( color: Colors.white, border: BorderDirectional( top: BorderSide( width: 1.0, color: Color.fromRGBO(0, 0, 0, 0.26)))), alignment: Alignment.center, child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation(Colors.deepPurple))); } else { return SizedBox.fromSize(size: Size.zero); } }); } }
Refer to the following code example.
class EmployeeDataGridSource extends DataGridSource { static const double perPage = 100; List<Employee> employees = []; void addDataGridRow(Employee data) { dataGridRows.add(DataGridRow(cells: [ DataGridCell<double>(columnName: 'employeeID', value: data.employeeID), DataGridCell<String>( columnName: 'employeeName', value: data.employeeName), DataGridCell<String>(columnName: 'designation', value: data.designation), DataGridCell<double>(columnName: 'salary', value: data.salary), ])); } Future loadMoreDataFromStream() async { final stream = collection .where('employeeID', isGreaterThan: employees.isEmpty ? 1000.0 : employees.last.employeeID, isLessThan: employees.isEmpty ? 1000.0 + perPage : employees.last.employeeID + perPage) .snapshots(); stream.listen((snapShot) async { await Future.forEach(snapShot.docs, (DocumentSnapshot element) { final Employee data = Employee.fromSnapshot(element); if (!employees .any((element) => element.employeeID == data.employeeID)) { employees.add(data); addDataGridRow(data); } }); updateDataGridDataSource(); }); } @override Future<void> handleLoadMoreRows() async { /// Perform delay to load the data to show the loading indicator if required. await Future.delayed(const Duration(milliseconds: 500), () { loadMoreDataFromStream(); }); } void updateDataGridDataSource() { notifyListeners(); } }
For more information, refer to Perform lazy loading in Flutter Data Table (SfDataGrid) demo.
In this blog post, we have seen the steps to lazy load data in the Syncfusion Flutter DataGrid (data table) while fetching data from Firebase. With this, you can load only the required data at once and load the remaining data on demand. This will enhance your productivity and reduce the loading time, too.
Syncfusion DataGrid is also available in our Blazor, ASP.NET (Core, MVC, WebForms), Angular, React, Vue, Xamarin, Flutter, UWP, WinForms, WPF, and WinUI platforms. Use them to build powerful applications!
For existing customers, the new version is available for download from the License and Downloads page. If you are not yet a Syncfusion customer, you can try our 30-day free trial to check out our available features. Also, try our samples from this GitHub location.
You can contact us through our support forum, Direct-Trac, or feedback portal. We are always happy to assist you!
).format(dataGridCell.value).toString() :
dataGridCell.value.toInt().toString(),
overflow: TextOverflow.ellipsis,
),
);
}
return Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text(dataGridCell.value.toString(),
overflow: TextOverflow.ellipsis),
);
}).toList());
}
void updateDataGridDataSource() {
notifyListeners();
}
}
Then, we have to initialize Firebase in the main() method to access the Firebase services.
Now, initialize the Firebase collection inside the DataGridSource class to fetch data from the cloud.
Now, let’s enable the lazy-loading feature in the Flutter DataGrid:
First, import the Flutter DataGrid and Firebase repository packages in the main.dart file using the following code.
We can perform lazy loading by using either of the following ways in the Flutter data table:
In this blog, we are going to lazy load data using the infinite-scrolling feature in the DataGrid:
Refer to the following code example.
Refer to the following code example.
For more information, refer to Perform lazy loading in Flutter Data Table (SfDataGrid) demo.
In this blog post, we have seen the steps to lazy load data in the Syncfusion Flutter DataGrid (data table) while fetching data from Firebase. With this, you can load only the required data at once and load the remaining data on demand. This will enhance your productivity and reduce the loading time, too.
Syncfusion DataGrid is also available in our Blazor, ASP.NET (Core, MVC, WebForms), Angular, React, Vue, Xamarin, Flutter, UWP, WinForms, WPF, and WinUI platforms. Use them to build powerful applications!
For existing customers, the new version is available for download from the License and Downloads page. If you are not yet a Syncfusion customer, you can try our 30-day free trial to check out our available features. Also, try our samples from this GitHub location.
You can contact us through our support forum, Direct-Trac, or feedback portal. We are always happy to assist you!