123 lines
3.7 KiB
Dart
123 lines
3.7 KiB
Dart
import 'package:flutter/material.dart';
|
|
class ReadOnlyTable extends StatelessWidget {
|
|
final List<String> headers;
|
|
final List<TableColumnWidth>? columnWidths;
|
|
final List<List<String>> data;
|
|
/// 回调,点击“操作”列时会触发,传入行索引
|
|
final void Function(int rowIndex)? onTapAction;
|
|
|
|
const ReadOnlyTable({
|
|
Key? key,
|
|
required this.headers,
|
|
required this.data,
|
|
this.columnWidths,
|
|
this.onTapAction,
|
|
}) : assert(columnWidths == null || columnWidths.length == headers.length),
|
|
super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
const cellPadding = EdgeInsets.all(8.0);
|
|
final headerStyle = const TextStyle(fontWeight: FontWeight.bold);
|
|
|
|
// 表头
|
|
Widget buildHeader() {
|
|
return Table(
|
|
border: TableBorder.all(color: Colors.black26),
|
|
columnWidths: columnWidths != null
|
|
? Map.fromIterables(
|
|
List.generate(headers.length, (i) => i),
|
|
columnWidths!,
|
|
)
|
|
: null,
|
|
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
|
children: [
|
|
TableRow(
|
|
decoration: const BoxDecoration(color: Color(0xFFE0E0E0)),
|
|
children: headers
|
|
.map((h) => Padding(
|
|
padding: cellPadding,
|
|
child: Text(h, style: headerStyle),
|
|
))
|
|
.toList(),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
// 有数据的表格
|
|
Widget buildDataTable() {
|
|
return Table(
|
|
border: TableBorder.all(color: Colors.black26),
|
|
columnWidths: columnWidths != null
|
|
? Map.fromIterables(
|
|
List.generate(headers.length, (i) => i),
|
|
columnWidths!,
|
|
)
|
|
: null,
|
|
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
|
children: [
|
|
for (int row = 0; row < data.length; row++)
|
|
TableRow(
|
|
children: List.generate(headers.length, (col) {
|
|
final text = col < data[row].length ? data[row][col] : '';
|
|
|
|
// 如果是最后一列(操作列),并且提供了回调,则渲染为可点击蓝色文本
|
|
// if (col == headers.length - 1 && onTapAction != null) {
|
|
// return Padding(
|
|
// padding: cellPadding,
|
|
// child: GestureDetector(
|
|
// onTap: () => onTapAction!(row),
|
|
// child: Text(
|
|
// text,
|
|
// style: const TextStyle(
|
|
// color: Colors.blue,
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// );
|
|
// }
|
|
|
|
return Padding(
|
|
padding: cellPadding,
|
|
child: Text(text, softWrap: true),
|
|
);
|
|
}),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
// 主体
|
|
if (data.isEmpty) {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
buildHeader(),
|
|
Container(
|
|
height: 50,
|
|
alignment: Alignment.center,
|
|
decoration: const BoxDecoration(
|
|
border: Border(
|
|
left: BorderSide(color: Colors.black26, width: 1),
|
|
right: BorderSide(color: Colors.black26, width: 1),
|
|
bottom: BorderSide(color: Colors.black26, width: 1),
|
|
),
|
|
),
|
|
child: const Text('暂无更多数据'),
|
|
),
|
|
],
|
|
);
|
|
} else {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
buildHeader(),
|
|
buildDataTable(),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|