flutter_integrated_whb/lib/pages/KeyProjects/SafeCheck/custom/safeCheck_table.dart

165 lines
5.7 KiB
Dart
Raw Normal View History

2025-08-14 15:05:48 +08:00
import 'dart:io';
import 'package:flutter/material.dart';
Widget HiddenListTable({
required List<dynamic> hiddenList,
required bool forbidEdit,
required String baseImgPath,
required String personSignImg,
required String personSignTime,
required void Function(Map<String, dynamic> item, int index) showHidden,
required void Function(Map<String, dynamic> item, int index) removeHidden,
required BuildContext context,
}) {
2025-09-05 09:16:54 +08:00
Widget _buildCell(String text, {bool isHeader = false, Alignment alignment = Alignment.center, double minWidth = 40}) {
2025-08-14 15:05:48 +08:00
return Container(
2025-09-05 09:16:54 +08:00
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 5),
2025-08-14 15:05:48 +08:00
alignment: alignment,
child: ConstrainedBox(
constraints: BoxConstraints(minWidth: minWidth),
child: Text(
text,
style: TextStyle(
fontWeight: isHeader ? FontWeight.bold : FontWeight.normal,
fontSize: 14,
color: isHeader ? Colors.black87 : Colors.black54,
),
),
),
);
}
TableRow _buildHeader() {
return TableRow(
decoration: BoxDecoration(color: Colors.grey.shade200),
children: [
_buildCell('序号', isHeader: true, alignment: Alignment.center),
_buildCell('隐患部位', isHeader: true),
_buildCell('隐患描述', isHeader: true),
_buildCell('操作', isHeader: true, alignment: Alignment.center),
],
);
}
TableRow _buildRow(Map<String, dynamic> item, int index) {
final partName = (item['HIDDENPART_NAME'] ?? '').toString();
final part = (item['HIDDENPART'] ?? '').toString();
final descr = (item['HIDDENDESCR'] ?? '').toString();
return TableRow(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey.shade300, width: 0.5),
),
),
children: [
_buildCell('${index + 1}', alignment: Alignment.center),
_buildCell(partName.isNotEmpty ? partName : part),
_buildCell(descr),
Padding(
padding: const EdgeInsets.symmetric(vertical: 6),
2025-09-05 09:16:54 +08:00
child: Align(
alignment: Alignment.center,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
2025-08-14 15:05:48 +08:00
IconButton(
2025-09-05 09:16:54 +08:00
icon: const Icon(Icons.info_outline, size: 20, color: Colors.blue,),
onPressed: () => showHidden(item, index),
padding: const EdgeInsets.all(4),
constraints: const BoxConstraints(minWidth: 24, minHeight: 24),
visualDensity: VisualDensity.compact,
2025-08-14 15:05:48 +08:00
),
2025-09-05 09:16:54 +08:00
if (forbidEdit)
IconButton(
icon: const Icon(Icons.delete_outline, size: 20, color: Colors.red,),
onPressed: () => removeHidden(item, index),
padding: const EdgeInsets.all(4),
constraints: const BoxConstraints(minWidth: 24, minHeight: 24),
visualDensity: VisualDensity.compact,
),
],
),
2025-08-14 15:05:48 +08:00
),
),
2025-09-05 09:16:54 +08:00
2025-08-14 15:05:48 +08:00
],
);
}
Widget _buildHeaderRowWidget() {
return Container(
decoration: BoxDecoration(color: Colors.grey.shade200),
child: Row(
children: [
2025-09-05 09:16:54 +08:00
Expanded(flex: 1, child: _buildCell('序号', isHeader: true, alignment: Alignment.center)),
2025-08-14 15:05:48 +08:00
Expanded(flex: 3, child: _buildCell('隐患部位', isHeader: true)),
Expanded(flex: 3, child: _buildCell('隐患描述', isHeader: true)),
Expanded(flex: 3, child: _buildCell('操作', isHeader: true, alignment: Alignment.center)),
],
),
);
}
2025-09-05 09:16:54 +08:00
// 用 LayoutBuilder 安全获取可用宽度(避免直接依赖 MediaQuery.of(context) 的 null 问题)
return LayoutBuilder(builder: (ctx, constraints) {
// 优先使用父级给出的约束宽度,否则退回到可选的 MediaQuery再 fallback 一个合理值
final double availableWidth = (constraints.maxWidth != double.infinity && constraints.maxWidth > 0)
? constraints.maxWidth
: ((MediaQuery.maybeOf(ctx)?.size.width ?? 400.0));
final tableWidth = (availableWidth - 20).clamp(200.0, double.infinity);
if (hiddenList.isEmpty) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SizedBox(
width: tableWidth,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
_buildHeaderRowWidget(),
Container(
height: 56,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey.shade300, width: 0.5),
),
),
alignment: Alignment.center,
child: Text(
'暂无数据',
style: TextStyle(fontSize: 14, color: Colors.black54),
),
),
],
),
),
);
}
2025-08-14 15:05:48 +08:00
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SizedBox(
width: tableWidth,
2025-09-05 09:16:54 +08:00
child: Table(
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
columnWidths: const {
0: FlexColumnWidth(1),
1: FlexColumnWidth(3),
2: FlexColumnWidth(3),
3: FlexColumnWidth(3),
},
border: TableBorder.symmetric(
inside: BorderSide(color: Colors.grey.shade300, width: 0.5),
),
// 把 map 转成 List<TableRow> 更明确、避免惰性展开可能的问题
2025-08-14 15:05:48 +08:00
children: [
2025-09-05 09:16:54 +08:00
_buildHeader(),
...hiddenList.asMap().entries.map((e) => _buildRow(e.value, e.key)).toList(),
2025-08-14 15:05:48 +08:00
],
),
),
);
2025-09-05 09:16:54 +08:00
});
2025-08-14 15:05:48 +08:00
}