184 lines
6.5 KiB
Dart
184 lines
6.5 KiB
Dart
|
|
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,
|
|||
|
|
}) {
|
|||
|
|
// 增加 textAlign 参数(默认根据 alignment 推断)
|
|||
|
|
Widget _buildCell(String text, {bool isHeader = false, Alignment alignment = Alignment.center, double minWidth = 30, TextAlign? textAlign}) {
|
|||
|
|
// 如果没有显式传 textAlign,根据 alignment 推断一个合理的值
|
|||
|
|
textAlign ??= (alignment == Alignment.center || alignment == Alignment.centerRight) ? TextAlign.center : TextAlign.left;
|
|||
|
|
|
|||
|
|
return Container(
|
|||
|
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 5),
|
|||
|
|
alignment: alignment,
|
|||
|
|
child: ConstrainedBox(
|
|||
|
|
constraints: BoxConstraints(minWidth: minWidth),
|
|||
|
|
child: Text(
|
|||
|
|
text,
|
|||
|
|
textAlign: textAlign,
|
|||
|
|
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['hiddenPartName'] ?? '').toString();
|
|||
|
|
final part = (item['hiddenPart'] ?? '').toString();
|
|||
|
|
final descr = (item['hiddenDesc'] ?? '').toString();
|
|||
|
|
|
|||
|
|
// 使用 styleFrom,不使用 MaterialStateProperty
|
|||
|
|
final ButtonStyle tinyButtonStyle = TextButton.styleFrom(
|
|||
|
|
padding: EdgeInsets.zero,
|
|||
|
|
minimumSize: const Size(0, 0),
|
|||
|
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|||
|
|
visualDensity: const VisualDensity(horizontal: -1, vertical: -1),
|
|||
|
|
// foregroundColor, textStyle 等也可以在这里指定,如果需要的话
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
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, horizontal: 0),
|
|||
|
|
child: Align(
|
|||
|
|
alignment: Alignment.center,
|
|||
|
|
child: Row(
|
|||
|
|
mainAxisSize: MainAxisSize.min,
|
|||
|
|
children: [
|
|||
|
|
TextButton(
|
|||
|
|
style: tinyButtonStyle,
|
|||
|
|
onPressed: () => showHidden(item, index),
|
|||
|
|
child: Text(
|
|||
|
|
forbidEdit ? '编辑' : '查看',
|
|||
|
|
style: const TextStyle(color: Colors.blue, fontSize: 14),
|
|||
|
|
),
|
|||
|
|
),
|
|||
|
|
if (forbidEdit)
|
|||
|
|
...[
|
|||
|
|
const SizedBox(width: 15), // 精确控制间距
|
|||
|
|
TextButton(
|
|||
|
|
style: tinyButtonStyle,
|
|||
|
|
onPressed: () => removeHidden(item, index),
|
|||
|
|
child: const Text(
|
|||
|
|
'删除',
|
|||
|
|
style: TextStyle(color: Colors.red, fontSize: 14),
|
|||
|
|
),
|
|||
|
|
),
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
],
|
|||
|
|
),
|
|||
|
|
),
|
|||
|
|
),
|
|||
|
|
],
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
Widget _buildHeaderRowWidget() {
|
|||
|
|
return Container(
|
|||
|
|
decoration: BoxDecoration(color: Colors.grey.shade200),
|
|||
|
|
child: Row(
|
|||
|
|
children: [
|
|||
|
|
Expanded(flex: 1, child: _buildCell('序号', isHeader: true, alignment: Alignment.center)),
|
|||
|
|
// Expanded(flex: 3, child: _buildCell('隐患部位', isHeader: true)),
|
|||
|
|
Expanded(flex: 6, child: _buildCell('隐患描述', isHeader: true)),
|
|||
|
|
Expanded(flex: 3, child: _buildCell('操作', isHeader: true, alignment: Alignment.center)),
|
|||
|
|
],
|
|||
|
|
),
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 用 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),
|
|||
|
|
),
|
|||
|
|
),
|
|||
|
|
],
|
|||
|
|
),
|
|||
|
|
),
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return SingleChildScrollView(
|
|||
|
|
scrollDirection: Axis.horizontal,
|
|||
|
|
child: SizedBox(
|
|||
|
|
width: tableWidth,
|
|||
|
|
child: Table(
|
|||
|
|
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
|||
|
|
columnWidths: const {
|
|||
|
|
0: FlexColumnWidth(1),
|
|||
|
|
// 1: FlexColumnWidth(3),
|
|||
|
|
1: FlexColumnWidth(6),
|
|||
|
|
2: FlexColumnWidth(3),
|
|||
|
|
},
|
|||
|
|
border: TableBorder.symmetric(
|
|||
|
|
inside: BorderSide(color: Colors.grey.shade300, width: 0.5),
|
|||
|
|
),
|
|||
|
|
// 把 map 转成 List<TableRow> 更明确、避免惰性展开可能的问题
|
|||
|
|
children: [
|
|||
|
|
_buildHeader(),
|
|||
|
|
...hiddenList.asMap().entries.map((e) => _buildRow(e.value, e.key)).toList(),
|
|||
|
|
],
|
|||
|
|
),
|
|||
|
|
),
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
}
|