数据表格是B端中常见的一个组件,主要用于展示数据,帮助用户根据浏览数据得出自己所需的内容,在最近的APP的开发中,公司也要求我在APP中实现一样的组件,但是在Web端中有成熟的组件库直接使用,比如Element-Plus
、Antd
等等,那在Flutter
可以使用第三方库syncfusion_flutter_datagrid
来帮助我们快速实现该功能
第三方库地址:pub.dev/packages/sy...
入门
syncfusion_flutter_datagrid
是Flutter一款强大的表格插件,它可以帮助你实现数据表格特色。
使用该插件的步骤可以大概分为以下步骤
- 为展示的数据创建对应的数据对象
- 创建数据源,继承
DataGridSource
,重写表格行 - 实现
SfDataGrid
,创建表头,传入数据源,完成表格数据渲染
在了解完实现基本步骤后,接下来我们可以跟着步骤实现一个简单的数据表格,实践出真知
创建数据对象
先定义结构对象
dart
class Book {
final int? id;
final String? bookName;
final String? author;
final double? price;
final String? publicTime;
Book({
required this.id,
required this.bookName,
required this.author,
required this.price,
required this.publicTime,
});
}
生成数据源
在这一步就进行对每个数据的操作或者单元格的设置等等操作,比如满足指定条件单元格变色
、数据渲染展示几位小数、与其他字段合并展示等
,可操作性很大,这些等到后面的示例中会进行演示,此处只做简单的创建
php
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:table_demo/book.dart';
class BookTableSource extends DataGridSource {
// 表格行数组
List<DataGridRow> _bookTableRow = [];
// 表格数据
List<Book> books = [
Book(id: 1, bookName: "红楼梦", author: "曹雪芹", price: 18.8, publicTime: "清代"),
Book(id: 2, bookName: "西游记", author: "吴承恩", price: 20.5, publicTime: "明代"),
Book(id: 3, bookName: "水浒传", author: "施耐庵", price: 19.0, publicTime: "元末明初"),
Book(id: 4, bookName: "三国演义", author: "罗贯中", price: 22.0, publicTime: "元末明初"),
Book(id: 5, bookName: "论语", author: "孔子", price: 15.0, publicTime: "春秋"),
Book(id: 6, bookName: "道德经", author: "老子", price: 16.0, publicTime: "春秋"),
Book(id: 7, bookName: "资治通鉴", author: "司马光", price: 25.0, publicTime: "北宋"),
Book(id: 8, bookName: "史记", author: "司马迁", price: 23.0, publicTime: "西汉"),
Book(id: 9, bookName: "诗经", author: "多人", price: 14.0, publicTime: "西周"),
Book(id: 10, bookName: "孙子兵法", author: "孙武", price: 17.0, publicTime: "春秋"),
];
BookTableSource(List<Book> books) {
// 遍历表格数据,创建对应的表格行
_bookTableRow = books.map<DataGridRow>((book) {
return DataGridRow(cells: [
DataGridCell(columnName: "id", value: book.id),
DataGridCell(columnName: "bookName", value: book.bookName),
DataGridCell(columnName: "author", value: book.author),
DataGridCell(columnName: "price", value: book.price),
DataGridCell(columnName: "publicTime", value: book.publicTime),
]);
}).toList();
}
@override
List<DataGridRow> get rows => _bookTableRow;
@override
DataGridRowAdapter? buildRow(DataGridRow row) {
// 具体的渲染
return DataGridRowAdapter(
return Container(
alignment: Alignment.center,
child: Text(
cell.value.toString(),
// 文字样式
style: const TextStyle(fontSize: 14, color: Colors.black87),
),
);
}).toList());
}
}
在遍历数据源的操作中,我们遍历了书籍数组的每本书,并将每本书的数据创建对应的单元格,并将数据赋值给改单元格,这个提高了我们对数据的可操作性
数据渲染
在准备好数据源之后,就可以使用SfDataGrid
组件渲染数据,在SfDataGrid
必传两个参数source:数据源
、columns:表格列,定义每一列的对应数据的字段以及要展示的字段名称
less
SfDataGrid(
// 数据源
source: BookTableSource(books),
// 表格列:注意 数据源的 列数 一定要与 表格列数 一致
columns: <GridColumn>[
GridColumn(
// 字段名(field):与数据源的字段名要保持一致
columnName: "id",
// 字段名称(label)
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.center,
child: const Text(
'id',
))),
GridColumn(
columnName: "bookName",
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.center,
child: const Text(
'名称',
))),
GridColumn(
columnName: "author",
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.center,
child: const Text(
'作者',
))),
GridColumn(
columnName: "price",
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.center,
child: const Text(
'价格',
))),
GridColumn(
columnName: "publicTime",
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.center,
child: const Text(
'发布时间',
))),
]
)
实现效果
SfDataGrid常见参数
属性名 | 属性值 | 描述 |
---|---|---|
source | DataGridSource | 数据源(必需) |
columns | GridColumn[] | 表头(必需) |
shrinkWrapRows | bool | 表格高度自增 |
shrinkWrapColumns | bool | 表格宽度自增 |
allowSwiping | bool | 禁止滑动 |
rowHeight | double | 设置行高 |
headerRowHeight | double | 设置表头高度 |
headerGridLinesVisibility | GridLinesVisibility | 设置表头网格线 |
gridLinesVisibility | GridLinesVisibility | 显示行和列的分割线 |
columnWidthMode | ColumnWidthMode | 设置列宽模式 |
可编辑单元格
SfDataGrid
允许使用各种小部件来加载数据,根据这个可以帮助我们实现可编辑单元格功能,只需要在入门案例的数据源中,将Container
小部件改为可输入的TextField
小部件即可
BookTableSource
less
@override
DataGridRowAdapter? buildRow(DataGridRow row) {
// 具体的渲染
return DataGridRowAdapter(
cells: row.getCells().map<Widget>((cell) {
return TextField(
controller: TextEditingController(text: cell.value.toString()),
);
}).toList());
}
自定义样式
表头样式自定义
在入门案例中,我们使用SfDataGrid
在渲染表头上是使用的Container
小部件,那么我们对于Container
的设置就会影响到数据表格表头的展示,我们可以为它加上边框、背景颜色
等等,就可以实现表格的自定义样式
示例
less
GridColumn(
// 字段名(field):与数据源的字段名要保持一致
columnName: "id",
// 字段名称(label)
label: Container(
// 设置内边距
padding: const EdgeInsets.all(16.0),
// 对齐方式
alignment: Alignment.center,
// 背景设置
decoration: BoxDecoration(
// 背景颜色
color: Colors.blue,
// 边框
border: Border.all(color: Colors.grey),
),
child: const Text(
'id',
// 文字样式
style: TextStyle(fontSize: 16, color: Colors.white),
)
)
),
表格行自定义样式
表格的自定义样式同理,在此基础上,尝试实现表格的隔行换色
示例
less
@override
DataGridRowAdapter? buildRow(DataGridRow row) {
// 获取 单元格 在列表中的索引位置
int index = _bookTableRow.indexOf(row);
// 具体的渲染
return DataGridRowAdapter(
cells: row.getCells().map<Widget>((cell) {
return Container(
alignment: Alignment.center,
decoration: BoxDecoration(
// 判断是单双,实现隔行换色
color: index % 2 == 0 ? Colors.white10 : Colors.blue[200]!,
// 添加边框
border: Border.all(color: Colors.grey),
),
child: Text(
cell.value.toString(),
// 文字样式
style: const TextStyle(fontSize: 14, color: Colors.black87),
),
);
}).toList());
}
个性化数据
在上面的例子中,我们所展示的数据都是没有特殊要求,正常展示的,但是根据业务需求,有的数据需要进行特殊处理,如果想对数据进行特殊处理,那么可以在创建数据源的时候进行操作,接下来就以几个示例展示
价格渲染带单位
要求:每本书籍的价格带价格单位
less
BookTableSource(List<Book> books) {
// 遍历数据源,创建对应的表格行
_bookTableRow = books.map<DataGridRow>((book) {
// 价格数据展示:带单位 元
String price = "${book.price}元";
return DataGridRow(cells: [
DataGridCell(columnName: "id", value: book.id),
DataGridCell(columnName: "bookName", value: book.bookName),
DataGridCell(columnName: "author", value: book.author),
DataGridCell(columnName: "price", value: price),
DataGridCell(columnName: "publicTime", value: book.publicTime),
]);
}).toList();
}
高价书籍价格单元格变色
要求:书籍超过20,价格单元格红色高亮
less
@override
DataGridRowAdapter? buildRow(DataGridRow row) {
// 具体的渲染
return DataGridRowAdapter(
cells: row.getCells().map<Widget>((cell) {
// 首先需要知道是否是 价格 列
bool isPriceColumn = cell.columnName == "price";
// 如果是价格列,再判断是否超过指定价格
bool flag = isPriceColumn && double.parse(cell.value.toString().replaceAll("元", "")) > 20;
return Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: flag ? Colors.red : Colors.white10,
// 添加边框
border: Border.all(color: Colors.grey),
),
child: Text(
cell.value.toString(),
// 文字样式
style: const TextStyle(fontSize: 14, color: Colors.black87),
),
);
}).toList());
}
通过创建、渲染
两个方法,我们可以在两个方法当中实现我们对数据的特殊处理或者数据表格的个性化的展示
总结
SfDataGrid
通过三个步骤实现数据表格
- 创建数据对象
- 生成数据源
- 渲染数据
在生成数据源的步骤中为我们提供操作数据的许多可能性,使我们可以对数据表格实现高定制,打造出我们需要的数据表格,那本章在基本入门SfDataGrid
,下一章就到对数据表格的分页、下拉加载功能的探究,欢迎继续观看。