让安卓也能玩出Element-Plus的表格效果

数据表格是B端中常见的一个组件,主要用于展示数据,帮助用户根据浏览数据得出自己所需的内容,在最近的APP的开发中,公司也要求我在APP中实现一样的组件,但是在Web端中有成熟的组件库直接使用,比如Element-PlusAntd等等,那在Flutter可以使用第三方库syncfusion_flutter_datagrid来帮助我们快速实现该功能

第三方库地址:pub.dev/packages/sy...

入门

syncfusion_flutter_datagrid是Flutter一款强大的表格插件,它可以帮助你实现数据表格特色。

使用该插件的步骤可以大概分为以下步骤

  1. 为展示的数据创建对应的数据对象
  2. 创建数据源,继承DataGridSource,重写表格行
  3. 实现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通过三个步骤实现数据表格

  1. 创建数据对象
  2. 生成数据源
  3. 渲染数据

在生成数据源的步骤中为我们提供操作数据的许多可能性,使我们可以对数据表格实现高定制,打造出我们需要的数据表格,那本章在基本入门SfDataGrid,下一章就到对数据表格的分页、下拉加载功能的探究,欢迎继续观看。

相关推荐
Myli_ing18 分钟前
考研倒计时-配色+1
前端·javascript·考研
余道各努力,千里自同风20 分钟前
前端 vue 如何区分开发环境
前端·javascript·vue.js
软件小伟29 分钟前
Vue3+element-plus 实现中英文切换(Vue-i18n组件的使用)
前端·javascript·vue.js
醉の虾1 小时前
Vue3 使用v-for 渲染列表数据后更新
前端·javascript·vue.js
张小小大智慧1 小时前
TypeScript 的发展与基本语法
前端·javascript·typescript
hummhumm1 小时前
第 22 章 - Go语言 测试与基准测试
java·大数据·开发语言·前端·python·golang·log4j
asleep7011 小时前
第8章利用CSS制作导航菜单
前端·css
hummhumm1 小时前
第 28 章 - Go语言 Web 开发入门
java·开发语言·前端·python·sql·golang·前端框架
幼儿园的小霸王2 小时前
通过socket设置版本更新提示
前端·vue.js·webpack·typescript·前端框架·anti-design-vue
疯狂的沙粒2 小时前
对 TypeScript 中高级类型的理解?应该在哪些方面可以更好的使用!
前端·javascript·typescript