该项目为flutter表格的初级版,后续更完善的版本已发布文章:Flutter用700行代码纯手工自定义绘制表格控件KqTablehttps://blog.csdn.net/u012800952/article/details/129549252?spm=1001.2014.3001.5502
- 演示
- 功能
1.支持动态数据绘制。数据格式[[row],[row],...]。
2.支持表格中文字的大小与颜色设置。
3.支持控件宽高设置。
4.支持设置表格的格子背景颜色与边框颜色。
5.支持固定上下左右行列,固定遵循格式,代表上下左右固定的行与列数:[int,int,int,int]
6.支持指定任意行列的颜色,设置格式:[TableColor,TableColor,...],TableColor有两个子函数。设置行颜色的RowColor与设置列颜色的RowColor。
7.支持单元格点击回调,回调会返回所点击的单元格的对应数据对象T。
8.支持列宽度拖拽,在第一行位置按住列分隔线便可拖拽列宽度。
- 代码
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
class KqTable<T> extends StatefulWidget {
/// 控件数据
final List<List<T>> data;
/// 文本大小
final double fontSize;
/// 文本颜色
final Color textColor;
/// 控件宽度
final double width;
/// 控件高度
final double height;
/// 表格颜色
final Color tableColor;
/// 表格边框颜色
final Color tableBorderColor;
/// 上下左右固定行数值[int,int,int,int]
final List<int> lockList;
/// 指定特定行或者列的颜色,行使用[RowColor],列使用[ColumnColor]
final List<TableColor> colorList;
/// 点击单元格回调
final Function(T data)? onTap;
const KqTable(
{super.key,
required this.data,
this.fontSize = 14,
this.textColor = Colors.black,
this.width = 300,
this.height = 200,
this.tableColor = Colors.white,
this.tableBorderColor = Colors.blueAccent,
this.lockList = const [1, 0, 1, 0],
this.colorList = const [
RowColor(0, Colors.grey),
RowColor(5, Colors.grey),
ColumnColor(0, Colors.grey),
ColumnColor(6, Colors.grey)
],
this.onTap});
@override
State<StatefulWidget> createState() => _KqTableState<T>();
}
class _KqTableState<T> extends State<KqTable<T>> {
///边线判断误差,用于判定拖拽列宽时是否点击在列线上的判定
final _columnWidthOffset = 4;
/// x方向偏移量
double _offsetDx = 0;
/// y方向偏移量
double _offsetDy = 0;
/// x方向误差量
double _diffOffsetDx = 0;
/// y方向误差量
double _diffOffsetDy = 0;
/// 行数
int _rowLength = 0;
/// 列数
int _columnLength = 0;
/// 每列的行文本最大宽度列表[[原宽度,调整后宽度],[原宽度,调整后宽度],...]
final List<List<double>> _rowWidthList = [];
double _columnHeight = 0;
/// 表格总宽度
double _tableWidth = 0;
/// 表格总高度
double _tableHeight = 0;
/// 按下时当前单元格的对象
T? _operateTableData;
/// 当前手势是否滑动
bool _operateIsMove = false;
/// 当前是否处于拖拽状态
bool _operateIsDrag = false;
/// 当前正在拖拽第几列的边线
int _operateColumnLineIndex = 0;
/// 当前正在拖拽边线前面累加的宽度值
double _operateTotalWidth = 0;
@override
void initState() {
super.initState();
_initData();
}
void _initData() {
_rowLength = widget.data[0].length;
_columnLength = widget.data.length;
for (int i = 0; i < _rowLength; i++) {
double maxWidth = 0;
for (int j = 0;