import 'package:flutter/material.dart'; class ReadOnlyTable extends StatelessWidget { final List headers; final List? columnWidths; final List> 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(), ], ); } } }