Latest source merged from Syncfusion
This commit is contained in:
Родитель
043b1bda8e
Коммит
e7a657abc0
|
@ -0,0 +1,313 @@
|
|||
---
|
||||
layout: post
|
||||
title: Load More in Flutter DataGrid | DataTable | Syncfusion
|
||||
description: Learn about how to load more rows to the Syncfusion Flutter DataGrid at runtime and how to achieve load more through infinite scrolling and load more button.
|
||||
platform: flutter
|
||||
control: SfDataGrid
|
||||
documentation: ug
|
||||
---
|
||||
|
||||
# Load more in Flutter Datagrid
|
||||
|
||||
The datagrid provides support to display an interactive view when the grid reaches its maximum offset while scrolling down. You can use [loadMoreViewBuilder](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid/loadMoreViewBuilder.html) builder to display the view at bottom of datagrid.
|
||||
|
||||
You should override the [DataGridSource.handleLoadMoreRows](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/DataGridSource/handleLoadMoreRows.html) method to load more rows and then notify the datagrid about the changes. The `DataGridSource.handleLoadMoreRows` can be called to load more rows from this builder by using the [loadMoreRows](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/LoadMoreRows.html) function which is passed as a parameter to this builder.
|
||||
|
||||
## Infinite scrolling
|
||||
|
||||
Infinite Scrolling is an approach that can be used to load more rows to the datagrid whenever the datagrid reaches the bottom without user interaction.
|
||||
|
||||
The following example demonstrates infinite scrolling by showing the circular progress indicator until the rows are loaded when the datagrid reaches the bottom,
|
||||
|
||||
{% tabs %}
|
||||
{% highlight Dart %}
|
||||
|
||||
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SfDataGrid(
|
||||
source: employeeDataSource,
|
||||
loadMoreViewBuilder: (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);
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
columns: <GridColumn>[
|
||||
GridNumericColumn(mappingName: 'id', headerText: 'ID'),
|
||||
GridTextColumn(mappingName: 'name', headerText: 'Name'),
|
||||
GridTextColumn(mappingName: 'designation', headerText: 'Designation'),
|
||||
GridNumericColumn(mappingName: 'salary', headerText: 'Salary'),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
final List<String> _names = <String>[
|
||||
'Welli',
|
||||
'Blonp',
|
||||
'Folko',
|
||||
'Furip',
|
||||
'Folig',
|
||||
'Picco',
|
||||
'Frans',
|
||||
'Warth',
|
||||
'Linod',
|
||||
'Simop',
|
||||
'Merep',
|
||||
'Riscu',
|
||||
'Seves',
|
||||
'Vaffe',
|
||||
'Alfki'
|
||||
];
|
||||
|
||||
final List<String> _designation = <String>[
|
||||
'Project Lead',
|
||||
'Developer',
|
||||
'Manager',
|
||||
'Designer',
|
||||
'System Analyst',
|
||||
'CEO'
|
||||
];
|
||||
|
||||
List<Employee> _addMoreRows(List<Employee> employeeData, int count) {
|
||||
final Random _random = Random();
|
||||
int startIndex = employeeData.isNotEmpty ? employeeData.length : 0,
|
||||
endIndex = startIndex + count;
|
||||
for (int i = startIndex; i < endIndex; i++) {
|
||||
employeeData.add(Employee(
|
||||
1000 + i,
|
||||
_names[_random.nextInt(_names.length - 1)],
|
||||
_designation[_random.nextInt(_designation.length - 1)],
|
||||
10000 + _random.nextInt(10000),
|
||||
));
|
||||
}
|
||||
return employeeData;
|
||||
}
|
||||
|
||||
class EmployeeDataSource extends DataGridSource<Employee> {
|
||||
@override
|
||||
List<Employee> get dataSource => employees;
|
||||
|
||||
@override
|
||||
Object getValue(Employee employee, String columnName) {
|
||||
switch (columnName) {
|
||||
case 'id':
|
||||
return employee.id;
|
||||
break;
|
||||
case 'name':
|
||||
return employee.name;
|
||||
break;
|
||||
case 'salary':
|
||||
return employee.salary;
|
||||
break;
|
||||
case 'designation':
|
||||
return employee.designation;
|
||||
break;
|
||||
default:
|
||||
return ' ';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> handleLoadMoreRows() async {
|
||||
await Future.delayed(Duration(seconds: 5));
|
||||
_addMoreRows(employees, 15);
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
{% endhighlight %}
|
||||
{% endtabs %}
|
||||
|
||||
**NOTE**
|
||||
Download demo application from [GitHub](https://github.com/SyncfusionExamples/how-to-do-the-infinite-scrolling-in-syncfusion-flutter-datatable).
|
||||
|
||||
![flutter datagrid shows load more with infinite scrolling behavior](images/load-more/flutter-datagrid-load-more-infinite-scrolling.gif)
|
||||
|
||||
## Load more button
|
||||
|
||||
Showing load more button is an approach that can be used to load more rows to the datagrid by tapping a button that you load from the `SfDataGrid.loadMoreViewBuilder` builder. The button will be loaded when vertical scrolling is reached at the end of the datagrid.
|
||||
|
||||
The following example demonstrates how to show the button when vertical scrolling is reached at the end of the datagrid and display the circular indicator until the rows are loaded when you tap that button. In the onPressed flat button callback, you can call the `loadMoreRows` function to add more rows,
|
||||
|
||||
{% tabs %}
|
||||
{% highlight Dart %}
|
||||
|
||||
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SfDataGrid(
|
||||
source: employeeDataSource,
|
||||
loadMoreViewBuilder: (BuildContext context, LoadMoreRows loadMoreRows) {
|
||||
bool showIndicator = false;
|
||||
return StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
if (showIndicator) {
|
||||
return Container(
|
||||
height: 60.0,
|
||||
width: double.infinity,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: BorderDirectional(
|
||||
top: BorderSide(
|
||||
width: 1.0, color: Color.fromRGBO(0, 0, 0, 0.26)))),
|
||||
child: CircularProgressIndicator(
|
||||
valueColor: AlwaysStoppedAnimation(Colors.deepPurple)));
|
||||
} else {
|
||||
return Container(
|
||||
height: 60.0,
|
||||
width: double.infinity,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: BorderDirectional(
|
||||
top: BorderSide(
|
||||
width: 1.0, color: Color.fromRGBO(0, 0, 0, 0.26)))),
|
||||
child: Container(
|
||||
height: 36.0,
|
||||
width: 142.0,
|
||||
child: FlatButton(
|
||||
color: Colors.deepPurple,
|
||||
child:
|
||||
Text('LOAD MORE', style: TextStyle(color: Colors.white)),
|
||||
onPressed: () async {
|
||||
if (context is StatefulElement &&
|
||||
context.state != null &&
|
||||
context.state.mounted) {
|
||||
setState(() {
|
||||
showIndicator = true;
|
||||
});
|
||||
}
|
||||
await loadMoreRows();
|
||||
if (context is StatefulElement &&
|
||||
context.state != null &&
|
||||
context.state.mounted) {
|
||||
setState(() {
|
||||
showIndicator = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
columns: <GridColumn>[
|
||||
GridNumericColumn(mappingName: 'id', headerText: 'ID'),
|
||||
GridTextColumn(mappingName: 'name', headerText: 'Name'),
|
||||
GridTextColumn(mappingName: 'designation', headerText: 'Designation'),
|
||||
GridNumericColumn(mappingName: 'salary', headerText: 'Salary'),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
final List<String> _names = <String>[
|
||||
'Welli',
|
||||
'Blonp',
|
||||
'Folko',
|
||||
'Furip',
|
||||
'Folig',
|
||||
'Picco',
|
||||
'Frans',
|
||||
'Warth',
|
||||
'Linod',
|
||||
'Simop',
|
||||
'Merep',
|
||||
'Riscu',
|
||||
'Seves',
|
||||
'Vaffe',
|
||||
'Alfki'
|
||||
];
|
||||
|
||||
final List<String> _designation = <String>[
|
||||
'Project Lead',
|
||||
'Developer',
|
||||
'Manager',
|
||||
'Designer',
|
||||
'System Analyst',
|
||||
'CEO'
|
||||
];
|
||||
|
||||
List<Employee> _addMoreRows(List<Employee> employeeData, int count) {
|
||||
final Random _random = Random();
|
||||
int startIndex = employeeData.isNotEmpty ? employeeData.length : 0,
|
||||
endIndex = startIndex + count;
|
||||
for (int i = startIndex; i < endIndex; i++) {
|
||||
employeeData.add(Employee(
|
||||
1000 + i,
|
||||
_names[_random.nextInt(_names.length - 1)],
|
||||
_designation[_random.nextInt(_designation.length - 1)],
|
||||
10000 + _random.nextInt(10000),
|
||||
));
|
||||
}
|
||||
return employeeData;
|
||||
}
|
||||
|
||||
class EmployeeDataSource extends DataGridSource<Employee> {
|
||||
@override
|
||||
List<Employee> get dataSource => employees;
|
||||
|
||||
@override
|
||||
Object getValue(Employee employee, String columnName) {
|
||||
switch (columnName) {
|
||||
case 'id':
|
||||
return employee.id;
|
||||
break;
|
||||
case 'name':
|
||||
return employee.name;
|
||||
break;
|
||||
case 'salary':
|
||||
return employee.salary;
|
||||
break;
|
||||
case 'designation':
|
||||
return employee.designation;
|
||||
break;
|
||||
default:
|
||||
return ' ';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> handleLoadMoreRows() async {
|
||||
await Future.delayed(Duration(seconds: 5));
|
||||
_addMoreRows(employees, 15);
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
{% endhighlight %}
|
||||
{% endtabs %}
|
||||
|
||||
**NOTE**
|
||||
Download demo application from [GitHub](https://github.com/SyncfusionExamples/how-to-load-rows-on-demand-in-Syncfusion-Flutter-datatable).
|
||||
|
||||
![flutter datagrid shows load more button behavior](images/load-more/flutter-datagrid-load-more-button.gif)
|
|
@ -197,8 +197,8 @@ Widget build(BuildContext context) {
|
|||
source: _employeeDataSource,
|
||||
allowSorting: true,
|
||||
columns: [
|
||||
GridNumericColumn(mappingName: 'id', headerText: 'ID')
|
||||
..allowSorting = false,
|
||||
GridNumericColumn(mappingName: 'id', headerText: 'ID',
|
||||
allowSorting: false),
|
||||
GridTextColumn(mappingName: 'name', headerText: 'Name'),
|
||||
GridTextColumn(mappingName: 'city', headerText: 'City'),
|
||||
GridNumericColumn(mappingName: 'freight', headerText: 'Freight')
|
||||
|
@ -228,8 +228,8 @@ Widget build(BuildContext context) {
|
|||
source: _employeeDataSource,
|
||||
allowSorting: true,
|
||||
columns: [
|
||||
GridNumericColumn(mappingName: 'id', headerText: 'ID')
|
||||
..headerStyle = DataGridHeaderCellStyle(sortIconColor: Colors.redAccent),
|
||||
GridNumericColumn(mappingName: 'id', headerText: 'ID',
|
||||
headerStyle: DataGridHeaderCellStyle(sortIconColor: Colors.redAccent)),
|
||||
GridTextColumn(mappingName: 'name', headerText: 'Name'),
|
||||
GridTextColumn(mappingName: 'city', headerText: 'City'),
|
||||
GridNumericColumn(mappingName: 'freight', headerText: 'Freight')
|
||||
|
@ -253,14 +253,8 @@ Widget build(BuildContext context) {
|
|||
return Scaffold(
|
||||
body: SfDataGridTheme(
|
||||
data: SfDataGridThemeData(
|
||||
headerStyle: DataGridHeaderCellStyle(
|
||||
sortIconColor: Colors.redAccent,
|
||||
backgroundColor: SfDataGridThemeData(brightness: Brightness.light)
|
||||
.headerStyle
|
||||
.backgroundColor,
|
||||
textStyle: SfDataGridThemeData(brightness: Brightness.light)
|
||||
.headerStyle
|
||||
.textStyle)),
|
||||
headerStyle:
|
||||
DataGridHeaderCellStyle(sortIconColor: Colors.redAccent)),
|
||||
child: SfDataGrid(
|
||||
source: _employeeDataSource,
|
||||
allowSorting: true,
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
---
|
||||
layout: post
|
||||
title: Stacked Headers in Flutter DataGrid | DataTable | Syncfusion
|
||||
description: Learn about how to add stacked header rows and customize row height of stacked header rows in Syncfusion Flutter DataGrid.
|
||||
platform: flutter
|
||||
control: SfDataGrid
|
||||
documentation: ug
|
||||
---
|
||||
|
||||
# Stacked headers in Flutter Datagrid
|
||||
|
||||
The datagrid provides support to display an additional unbound header rows known as [StackedHeaderRows](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid/stackedHeaderRows.html) that are spanned across the DataGrid columns. You can group one or more columns under each stacked header.
|
||||
|
||||
Each [StackedHeaderRow](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/StackedHeaderRow-class.html) contains [cells](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/StackedHeaderRow/cells.html) that hold a list of [StackedHeaderCell](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/StackedHeaderCell-class.html) where each `StackedHeaderCell` contains a number of child columns. The [StackedHeaderCell.columnNames](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/StackedHeaderCell/columnNames.html) property returns the columns grouped under the stacked header row. The [GridColumn.mappingName](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/GridColumn/mappingName.html) is a unique name used for mapping specific child columns grouped under the same stacked header row. The [StackedHeaderCell.child](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/StackedHeaderCell/child.html) property is used to load any type of widget to the corresponding stacked header cell.
|
||||
|
||||
{% tabs %}
|
||||
{% highlight Dart %}
|
||||
|
||||
import 'package:syncfusion_flutter_core/theme.dart';
|
||||
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SfDataGridTheme(
|
||||
data: SfDataGridThemeData(
|
||||
headerStyle: DataGridHeaderCellStyle(
|
||||
backgroundColor: const Color(0xFFF1F1F1))),
|
||||
child: SfDataGrid(
|
||||
gridLinesVisibility: GridLinesVisibility.both,
|
||||
headerGridLinesVisibility: GridLinesVisibility.both,
|
||||
source: _productDataSource,
|
||||
columns: <GridColumn>[
|
||||
GridNumericColumn(mappingName: 'orderId', headerText: 'ID'),
|
||||
GridTextColumn(mappingName: 'customerName', headerText: 'Name'),
|
||||
GridNumericColumn(mappingName: 'productId', headerText: 'ID'),
|
||||
GridTextColumn(mappingName: 'product', headerText: 'Product'),
|
||||
],
|
||||
stackedHeaderRows: <StackedHeaderRow>[
|
||||
StackedHeaderRow(cells: [
|
||||
StackedHeaderCell(
|
||||
columnNames: ['orderId', 'customerName'],
|
||||
child: Container(
|
||||
color: const Color(0xFFF1F1F1),
|
||||
child: Center(child: Text('Customer Details')))),
|
||||
StackedHeaderCell(
|
||||
columnNames: ['productId', 'product'],
|
||||
child: Container(
|
||||
color: const Color(0xFFF1F1F1),
|
||||
child: Center(child: Text('Product Details'))))
|
||||
])
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
{% endhighlight %}
|
||||
{% endtabs %}
|
||||
|
||||
![flutter datagrid shows stacked headers](images/stacked-headers/flutter-stacked-headers.png)
|
||||
|
||||
## Multi stacked headers
|
||||
|
||||
You can provide multiple stacked headers to the datagrid by adding the multiple `StackedHeaderRow` to the `SfDataGrid.stackedHeaderRows` collection.
|
||||
|
||||
{% tabs %}
|
||||
{% highlight Dart %}
|
||||
|
||||
import 'package:syncfusion_flutter_core/theme.dart';
|
||||
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SfDataGridTheme(
|
||||
data: SfDataGridThemeData(
|
||||
headerStyle: DataGridHeaderCellStyle(
|
||||
backgroundColor: const Color(0xFFF1F1F1))),
|
||||
child: SfDataGrid(
|
||||
gridLinesVisibility: GridLinesVisibility.both,
|
||||
headerGridLinesVisibility: GridLinesVisibility.both,
|
||||
source: _productDataSource,
|
||||
columns: <GridColumn>[
|
||||
GridNumericColumn(mappingName: 'orderId', headerText: 'ID'),
|
||||
GridTextColumn(mappingName: 'customerName', headerText: 'Name'),
|
||||
GridNumericColumn(mappingName: 'productId', headerText: 'ID'),
|
||||
GridTextColumn(mappingName: 'product', headerText: 'Product'),
|
||||
],
|
||||
stackedHeaderRows: <StackedHeaderRow>[
|
||||
StackedHeaderRow(cells: [
|
||||
StackedHeaderCell(
|
||||
columnNames: ['orderId', 'customerName', 'productId', 'product'],
|
||||
child: Container(
|
||||
color: const Color(0xFFF1F1F1),
|
||||
child: Center(child: Text('Order Shipment Details')))),
|
||||
]),
|
||||
StackedHeaderRow(cells: [
|
||||
StackedHeaderCell(
|
||||
columnNames: ['orderId', 'customerName'],
|
||||
child: Container(
|
||||
color: const Color(0xFFF1F1F1),
|
||||
child: Center(child: Text('Customer Details')))),
|
||||
StackedHeaderCell(
|
||||
columnNames: ['productId', 'product'],
|
||||
child: Container(
|
||||
color: const Color(0xFFF1F1F1),
|
||||
child: Center(child: Text('Product Details'))))
|
||||
])
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
{% endhighlight %}
|
||||
{% endtabs %}
|
||||
|
||||
![flutter datagrid shows multi stacked headers](images/stacked-headers/flutter-multi-stacked-headers.png)
|
||||
|
||||
## Changing row height of stacked headers
|
||||
|
||||
You can change the height of stacked header rows by using the [SfDataGrid.onQueryRowHeight](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid/onQueryRowHeight.html) callback.
|
||||
|
||||
You can also change the row height of stacked header row and column header row by using [headerRowHeight](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid/headerRowHeight.html) property.
|
||||
|
||||
{% tabs %}
|
||||
{% highlight Dart %}
|
||||
|
||||
import 'package:syncfusion_flutter_core/theme.dart';
|
||||
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SfDataGridTheme(
|
||||
data: SfDataGridThemeData(
|
||||
headerStyle: DataGridHeaderCellStyle(
|
||||
backgroundColor: const Color(0xFFF1F1F1))),
|
||||
child: SfDataGrid(
|
||||
gridLinesVisibility: GridLinesVisibility.both,
|
||||
headerGridLinesVisibility: GridLinesVisibility.both,
|
||||
source: _productDataSource,
|
||||
onQueryRowHeight: (RowHeightDetails details) {
|
||||
if (details.rowIndex == 0) {
|
||||
return 70.0;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
columns: <GridColumn>[
|
||||
GridNumericColumn(mappingName: 'orderId', headerText: 'ID'),
|
||||
GridTextColumn(mappingName: 'customerName', headerText: 'Name'),
|
||||
GridNumericColumn(mappingName: 'productId', headerText: 'ID'),
|
||||
GridTextColumn(mappingName: 'product', headerText: 'Product'),
|
||||
],
|
||||
stackedHeaderRows: <StackedHeaderRow>[
|
||||
StackedHeaderRow(cells: [
|
||||
StackedHeaderCell(
|
||||
columnNames: ['orderId', 'customerName'],
|
||||
child: Container(
|
||||
color: const Color(0xFFF1F1F1),
|
||||
child: Center(child: Text('Customer Details')))),
|
||||
StackedHeaderCell(
|
||||
columnNames: ['productId', 'product'],
|
||||
child: Container(
|
||||
color: const Color(0xFFF1F1F1),
|
||||
child: Center(child: Text('Product Details'))))
|
||||
])
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
{% endhighlight %}
|
||||
{% endtabs %}
|
||||
|
||||
![flutter datagrid shows customization of stacked header row heights](images/stacked-headers/flutter-stacked-header-row-height.png)
|
Загрузка…
Ссылка в новой задаче