Flutter可编辑表格插件flutter_editable_table的使用
Flutter可编辑表格插件flutter_editable_table的使用
1. 简介
flutter_editable_table
是一个Flutter插件,用于创建可自定义和可编辑的表格。该插件支持从JSON数据生成表格,并提供了丰富的配置选项,如表头、表体、表尾、添加/删除行等功能。
2. 使用步骤
2.1 添加依赖
在 pubspec.yaml
文件中添加 flutter_editable_table
依赖:
dependencies:
flutter_editable_table: any
2.2 导入库
在Dart文件中导入 flutter_editable_table
库:
import 'package:flutter_editable_table/flutter_editable_table.dart';
3. 创建可编辑表格
要创建一个新的可编辑表格,可以使用 EditableTable()
小部件,并提供JSON格式的数据。以下是一个完整的示例代码,展示了如何创建一个可编辑的表格并实现一些常用功能,如添加行、切换编辑模式等。
import 'package:flutter/material.dart';
import 'package:flutter_editable_table/constants.dart';
import 'package:flutter_editable_table/entities/table_entity.dart';
import 'package:flutter_editable_table/flutter_editable_table.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Editable Table',
builder: (context, child) {
return GestureDetector(
onTap: () {
WidgetsBinding.instance.focusManager.primaryFocus?.unfocus();
},
child: child,
);
},
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Editable Table'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _editableTableKey = GlobalKey<EditableTableState>();
// 表格数据
final data = {
"column_count": null,
"row_count": null,
"addable": true,
"removable": true,
"caption": {
"layout_direction": "row",
"main_caption": {
"title": "表格标题",
"display": true,
"editable": false,
"style": {
"font_weight": "bold",
"font_size": 18.0,
"font_color": "#333333",
"horizontal_alignment": "center",
"vertical_alignment": "center",
"text_align": "center"
}
},
"sub_caption": {
"title": null,
"display": true,
"editable": true,
"input_decoration": {
"min_lines": 1,
"max_lines": 1,
"max_length": 64,
"hint_text": "请输入副标题",
"fill_color": null
},
"constrains": {"required": true},
"style": {
"font_weight": "normal",
"font_size": 14.0,
"font_color": "#333333",
"horizontal_alignment": "center",
"vertical_alignment": "center",
"text_align": "center"
}
}
},
"columns": [
{
"primary_key": true,
"name": "id",
"type": "int",
"format": null,
"description": null,
"display": false,
"editable": false,
"style": {
"font_weight": "bold",
"font_size": 14.0,
"font_color": "#333333",
"background_color": "#b5cfd2",
"horizontal_alignment": "center",
"vertical_alignment": "center",
"text_align": "center"
}
},
{
"auto_increase": true,
"type": "int",
"format": "Step __VALUE__",
"description": null,
"display": true,
"editable": false,
"width_factor": 0.2,
"style": {
"font_weight": "bold",
"font_size": 14.0,
"font_color": "#333333",
"background_color": "#b5cfd2",
"horizontal_alignment": "center",
"vertical_alignment": "center",
"text_align": "center"
}
},
{
"name": "name",
"title": "姓名",
"type": "string",
"format": null,
"description": "用户姓名",
"display": true,
"editable": true,
"width_factor": 0.4,
"input_decoration": {
"min_lines": 1,
"max_lines": 1,
"max_length": 128,
"hint_text": "请输入姓名"
},
"constrains": {"required": true},
"style": {
"font_weight": "bold",
"font_size": 14.0,
"font_color": "#333333",
"background_color": "#b5cfd2",
"horizontal_alignment": "center",
"vertical_alignment": "center",
"text_align": "center"
}
},
{
"name": "age",
"title": "年龄",
"type": "integer",
"format": null,
"description": "年龄",
"display": true,
"editable": true,
"width_factor": 0.2,
"input_decoration": {
"min_lines": 1,
"max_lines": 1,
"max_length": 3,
"hint_text": "请输入年龄"
},
"constrains": {"required": true, "minimum": 1, "maximum": 120},
"style": {
"font_weight": "bold",
"font_size": 14.0,
"font_color": "#333333",
"background_color": "#b5cfd2",
"horizontal_alignment": "center",
"vertical_alignment": "center",
"text_align": "center"
}
},
{
"name": "desc",
"title": "描述",
"type": "string",
"format": null,
"description": "描述",
"display": true,
"editable": true,
"width_factor": 0.4,
"input_decoration": {
"min_lines": 3,
"max_lines": 5,
"max_length": 128,
"hint_text": "请输入描述"
},
"constrains": {"required": false, "minimum": 1, "maximum": 100},
"style": {
"font_weight": "bold",
"font_size": 14.0,
"font_color": "#333333",
"background_color": "#b5cfd2",
"horizontal_alignment": "center",
"vertical_alignment": "center",
"text_align": "center"
}
},
{
"name": "salary",
"title": "工资",
"type": "float",
"format": null,
"description": "工资",
"display": true,
"editable": true,
"width_factor": 0.2,
"input_decoration": {
"min_lines": 1,
"max_lines": 1,
"max_length": 128,
"hint_text": "请输入工资"
},
"constrains": {"required": true, "minimum": -100, "maximum": 10000},
"style": {
"font_weight": "bold",
"font_size": 14.0,
"font_color": "#333333",
"background_color": "#b5cfd2",
"horizontal_alignment": "center",
"vertical_alignment": "center",
"text_align": "center"
}
},
{
"name": "married",
"title": "已婚",
"type": "bool",
"format": null,
"description": "是否已婚",
"display": true,
"editable": true,
"width_factor": 0.12,
"constrains": {"required": false},
"style": {
"font_weight": "bold",
"font_size": 14.0,
"font_color": "#333333",
"background_color": "#b5cfd2",
"horizontal_alignment": "center",
"vertical_alignment": "center",
"text_align": "center"
}
},
{
"name": "d_o_m",
"title": "结婚日期",
"type": "date",
"format": null,
"description": "结婚日期",
"display": true,
"editable": true,
"width_factor": 0.3,
"input_decoration": {"hint_text": "请输入结婚日期"},
"style": {
"font_weight": "bold",
"font_size": 14.0,
"font_color": "#333333",
"background_color": "#b5cfd2",
"horizontal_alignment": "center",
"vertical_alignment": "center",
"text_align": "center"
}
},
{
"name": "l_s_t",
"title": "最后一次购物时间",
"type": "datetime",
"format": null,
"description": "最后一次购物时间",
"display": true,
"editable": true,
"width_factor": 0.5,
"input_decoration": {
"hint_text": "请输入最后一次购物时间"
},
"constrains": {"required": true},
"style": {
"font_weight": "bold",
"font_size": 14.0,
"font_color": "#333333",
"background_color": "#b5cfd2",
"horizontal_alignment": "center",
"vertical_alignment": "center",
"text_align": "center"
}
}
],
"rows": [
{
"id": 0,
"name": "Tom",
"age": 18,
"desc": "我是Tom",
"salary": 1000.5,
"married": false,
"d_o_m": null,
"l_s_t": null
},
{
"id": 1,
"name": "Sam",
"age": 20,
"desc": null,
"salary": 1234.5,
"married": false,
"d_o_m": null,
"l_s_t": "2021-06-23 11:28"
},
{
"id": 2,
"name": "Olivia",
"age": 25,
"desc": null,
"salary": 2500.0,
"married": true,
"d_o_m": "2020-10-01",
"l_s_t": "2021-01-08 20:20"
},
{
"id": 3,
"name": "Liam",
"age": 23,
"desc": null,
"salary": 3000.0,
"married": true,
"d_o_m": "2018-08-01",
"l_s_t": "2021-11-11 18:10"
},
{
"id": 4,
"name": "David",
"age": 26,
"desc": null,
"salary": 2300.0,
"married": true,
"d_o_m": "2019-03-05",
"l_s_t": "2021-12-08 21:30"
},
],
"footer": {
"layout_direction": "row",
"content": [
{
"title": "平均年龄: 22.4",
"display": true,
"editable": false,
"style": {
"font_weight": "normal",
"font_size": 14.0,
"font_color": "#333333",
"horizontal_alignment": "center",
"vertical_alignment": "center",
"text_align": "center"
}
},
{
"title": "已婚人数: 3",
"display": true,
"editable": false,
"style": {
"font_weight": "normal",
"font_size": 14.0,
"font_color": "#333333",
"horizontal_alignment": "center",
"vertical_alignment": "center",
"text_align": "center"
}
},
{
"title": null,
"display": true,
"editable": true,
"input_decoration": {
"min_lines": 1,
"max_lines": 1,
"max_length": 64,
"hint_text": "请输入身份",
"fill_color": null
},
"constrains": {"required": true},
"style": {
"font_weight": "normal",
"font_size": 14.0,
"font_color": "#333333",
"horizontal_alignment": "center",
"vertical_alignment": "center",
"text_align": "center"
}
}
]
}
};
bool editing = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.print),
onPressed: () {
print(_editableTableKey.currentState?.currentData);
},
),
title: Text(widget.title),
centerTitle: true,
actions: [
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
WidgetsBinding.instance.focusManager.primaryFocus?.unfocus();
_editableTableKey.currentState?.addRow();
},
child: Icon(Icons.add),
),
SizedBox(width: 8.0),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
WidgetsBinding.instance.focusManager.primaryFocus?.unfocus();
_editableTableKey.currentState?.readOnly = editing;
setState(() {
editing = !editing;
});
if (!editing) {
print(
'表格填写状态: ${_editableTableKey.currentState?.isFilled}');
}
},
child: Icon(!editing ? Icons.edit : Icons.check),
),
SizedBox(width: 14.0),
],
),
body: SingleChildScrollView(
child: EditableTable(
key: _editableTableKey,
data: data,
entity: TableEntity.fromJson(data),
readOnly: true,
tablePadding: EdgeInsets.all(8.0),
captionBorder: Border(
top: BorderSide(color: Color(0xFF999999)),
left: BorderSide(color: Color(0xFF999999)),
right: BorderSide(color: Color(0xFF999999)),
),
headerBorder: Border.all(color: Color(0xFF999999)),
rowBorder: Border.all(color: Color(0xFF999999)),
footerBorder: Border.all(color: Color(0xFF999999)),
removeRowIcon: Icon(
Icons.remove_circle_outline,
size: 24.0,
color: Colors.redAccent,
),
addRowIcon: Icon(
Icons.add_circle_outline,
size: 24.0,
color: Colors.white,
),
addRowIconContainerBackgroundColor: Colors.blueAccent,
formFieldAutoValidateMode: AutovalidateMode.always,
onRowRemoved: (row) {
print('行被移除: ${row.toString()}');
},
onRowAdded: () {
print('行被添加');
},
onFilling: (FillingArea area, dynamic value) {
print('正在填写: ${area.toString()}, 值: ${value.toString()}');
},
onSubmitted: (FillingArea area, dynamic value) {
print('提交: ${area.toString()}, 值: ${value.toString()}');
},
),
),
);
}
}
4. 功能说明
- 添加行:通过点击右上角的
+
按钮,可以在表格中添加新行。 - 切换编辑模式:点击编辑图标(铅笔)可以切换表格的编辑模式。在编辑模式下,用户可以修改表格中的内容;点击对勾图标可以保存编辑内容,并检查表格是否已填写完整。
- 打印表格数据:点击左上角的打印图标,可以将当前表格的数据打印到控制台。
- 移除行:每行末尾有一个删除按钮,点击可以移除该行。
- 回调函数:
onRowRemoved
:当某一行被移除时触发。onRowAdded
:当新行被添加时触发。onFilling
:当用户正在填写某个单元格时触发。onSubmitted
:当用户提交某个单元格的内容时触发。
5. 获取表格数据
可以通过 GlobalKey
获取表格的当前数据:
final _editableTableKey = GlobalKey<EditableTableState>();
// 获取当前表格数据
print(_editableTableKey.currentState?.currentData);
6. 动态切换只读模式
可以通过 GlobalKey
动态切换表格的只读模式:
_editableTableKey.currentState?.readOnly = true; // 设置为只读模式
_editableTableKey.currentState?.readOnly = false; // 设置为可编辑模式
7. 检查填写状态
如果表格中有必填字段未填写,isFilled
将返回 false
:
print(_editableTableKey.currentState?.isFilled);
更多关于Flutter可编辑表格插件flutter_editable_table的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter可编辑表格插件flutter_editable_table的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用 flutter_editable_table
插件的简单示例代码。这个插件允许你在 Flutter 应用中创建可编辑的表格。
首先,确保你已经在 pubspec.yaml
文件中添加了 flutter_editable_table
依赖:
dependencies:
flutter:
sdk: flutter
flutter_editable_table: ^x.y.z # 请替换为最新版本号
然后运行 flutter pub get
来获取依赖。
接下来,创建一个 Flutter 应用,并在你的主 Dart 文件中使用 flutter_editable_table
插件。以下是一个完整的示例:
import 'package:flutter/material.dart';
import 'package:flutter_editable_table/flutter_editable_table.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Editable Table Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: EditableTableDemo(),
);
}
}
class EditableTableDemo extends StatefulWidget {
@override
_EditableTableDemoState createState() => _EditableTableDemoState();
}
class _EditableTableDemoState extends State<EditableTableDemo> {
final List<List<String>> data = [
['Name', 'Age', 'Email'],
['Alice', '30', 'alice@example.com'],
['Bob', '25', 'bob@example.com'],
['Charlie', '35', 'charlie@example.com'],
];
final List<String> headers = ['Name', 'Age', 'Email'];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Editable Table Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: EditableTable(
headers: headers,
rows: data,
onCellSubmitted: (row, col, newValue) {
setState(() {
data[row][col] = newValue;
});
},
cellDecoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey[300]!),
),
),
headerDecoration: BoxDecoration(
backgroundColor: Colors.grey[200],
),
cellTextStyle: TextStyle(fontSize: 18),
headerTextStyle: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
),
),
);
}
}
代码解释:
- 依赖导入:导入
flutter
和flutter_editable_table
包。 - 应用入口:定义
MyApp
类作为应用的入口,并设置主题和主页。 - 主页:创建
EditableTableDemo
类,它是一个有状态的组件,用于管理表格数据的状态。 - 数据定义:定义一个
data
列表,其中每个子列表代表表格的一行数据。headers
列表定义表格的列头。 - 构建 UI:在
build
方法中,使用Scaffold
和Padding
组件来布局,并在中间放置EditableTable
组件。 - EditableTable 参数:
headers
:表格的列头。rows
:表格的数据行。onCellSubmitted
:单元格编辑完成后的回调函数,用于更新数据。cellDecoration
和headerDecoration
:单元格和列头的装饰,如边框和背景颜色。cellTextStyle
和headerTextStyle
:单元格和列头的文本样式。padding
:单元格的内边距。
这个示例展示了如何使用 flutter_editable_table
插件来创建一个简单的可编辑表格,并处理用户输入来更新表格数据。你可以根据需要进一步自定义表格的样式和功能。