更新快检功能

This commit is contained in:
wyf
2026-03-10 12:01:00 +08:00
parent d0ae2a9f76
commit 6472baf993
48 changed files with 8046 additions and 120 deletions

View File

@@ -1,11 +1,188 @@
// import 'package:flutter/material.dart';
// import 'package:vbvs_app/common/color/appConstants.dart';
// import 'package:vbvs_app/common/util/FitTool.dart';
// import 'package:vbvs_app/common/util/MyUtils.dart';
// class StatusBarWithIndicator extends StatelessWidget {
// final int selectKey;
// final List<Map<String, dynamic>> showLabel;
// final IconData icon;
// final double gap; // 每段之间的间距
// final bool showCurrentValue; // 新增参数,控制是否显示当前值
// final String? currentValueText; // 可选的当前值文字如果不提供则使用选中的name
// const StatusBarWithIndicator({
// super.key,
// required this.selectKey,
// required this.showLabel,
// this.icon = Icons.favorite,
// this.gap = 8.0, // 默认 8.rpx 间距
// this.showCurrentValue = false, // 默认为false
// this.currentValueText,
// });
// @override
// Widget build(BuildContext context) {
// return LayoutBuilder(builder: (context, constraints) {
// final totalWidth = constraints.maxWidth;
// final itemCount = showLabel.length;
// // 每条线的宽度 = (总宽度 - 总间隔)/ 项数
// final totalGap = (itemCount - 1) * gap.rpx;
// final itemWidth = (totalWidth - totalGap) / itemCount;
// // 找到选中项的 index 和对应的数据
// final selectedIndex = showLabel.indexWhere((e) => e['key'] == selectKey);
// final selectedItem = selectedIndex >= 0 ? showLabel[selectedIndex] : null;
// final iconLeft = selectedIndex >= 0
// ? selectedIndex * (itemWidth + gap.rpx) + itemWidth / 2
// : 0.0;
// // 确定要显示的当前值文字
// String displayValue = '';
// if (showCurrentValue) {
// if (currentValueText != null) {
// displayValue = currentValueText!;
// } else if (selectedItem != null) {
// displayValue = selectedItem['name'] ?? '';
// }
// }
// return SizedBox(
// width: double.infinity,
// child: Stack(
// clipBehavior: Clip.none,
// children: [
// if (selectedIndex >= 0) ...[
// // 如果显示当前值,在箭头上方添加文字
// if (showCurrentValue && displayValue.isNotEmpty)
// Positioned(
// left: iconLeft,
// top: -50.rpx, // 调整位置,给文字留出空间
// child: Transform.translate(
// offset: Offset(-45.rpx, 0), // 图片宽度 45.rpx居中偏移
// child: Container(
// // padding: EdgeInsets.symmetric(
// // horizontal: 8.rpx,
// // vertical: 4.rpx,
// // ),
// // decoration: BoxDecoration(
// // color: selectedItem?['color'] ?? Colors.blue,
// // borderRadius: BorderRadius.circular(4.rpx),
// // boxShadow: [
// // BoxShadow(
// // color: Colors.black.withOpacity(0.1),
// // blurRadius: 4.rpx,
// // offset: Offset(0, 2.rpx),
// // ),
// // ],
// // ),
// child: Text(
// displayValue,
// style: TextStyle(
// fontSize: AppConstants().small_an_text_fontSize,
// color: themeController.currentColor.sc9,
// fontWeight: FontWeight.w500,
// ),
// ),
// ),
// ),
// ),
// // 箭头图片
// Positioned(
// left: iconLeft,
// top: showCurrentValue ? -20.rpx : -20.rpx, // 如果有文字,箭头位置稍下移
// child: Transform.translate(
// offset: Offset(-22.5.rpx, 0), // 图片宽度 45.rpx居中偏移
// child: Container(
// width: 45.rpx,
// height: 76.rpx,
// decoration: BoxDecoration(
// image: DecorationImage(
// image: AssetImage('assets/img/tip_arrow.gif'),
// fit: BoxFit.cover,
// ),
// ),
// ),
// ),
// ),
// ],
// // 条形图和文字标签
// Padding(
// padding: EdgeInsets.only(top: showCurrentValue ? 70.rpx : 50.rpx),
// child: Column(
// children: [
// // 条形段(带间距)
// Row(
// children: showLabel.asMap().entries.map((entry) {
// int index = entry.key;
// var item = entry.value;
// return Container(
// width: itemWidth,
// height: 15.rpx,
// margin: EdgeInsets.only(
// left: index == 0 ? 0 : gap.rpx,
// ),
// decoration: BoxDecoration(
// color: item['color'],
// borderRadius: BorderRadius.circular(0.rpx),
// ),
// );
// }).toList(),
// ),
// SizedBox(height: 12.rpx),
// // 名称文字
// Row(
// children: showLabel.asMap().entries.map((entry) {
// int index = entry.key;
// var item = entry.value;
// return Container(
// width: itemWidth,
// margin: EdgeInsets.only(
// left: index == 0 ? 0 : gap.rpx,
// ),
// alignment: Alignment.center,
// child: Text(
// item['name'],
// style: TextStyle(
// fontSize: 24.rpx,
// color: Colors.white,
// ),
// textAlign: TextAlign.center,
// ),
// );
// }).toList(),
// ),
// ],
// ),
// ),
// ],
// ),
// );
// });
// }
// }
import 'package:flutter/material.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
class StatusBarWithIndicator extends StatelessWidget {
final int selectKey;
final List<Map<String, dynamic>> showLabel;
final IconData icon;
final double gap; // 每段之间的间距
final bool showCurrentValue; // 控制是否显示当前值
final String? currentValueText; // 可选的当前值文字如果不提供则使用选中的name
final bool showRange; // 新增参数,控制是否显示范围
final String? Function(Map<String, dynamic> item)?
rangeTextBuilder; // 可选的范围文字构建器
const StatusBarWithIndicator({
super.key,
@@ -13,6 +190,10 @@ class StatusBarWithIndicator extends StatelessWidget {
required this.showLabel,
this.icon = Icons.favorite,
this.gap = 8.0, // 默认 8.rpx 间距
this.showCurrentValue = false, // 默认为false
this.currentValueText,
this.showRange = false, // 默认为false不显示范围
this.rangeTextBuilder, // 自定义范围文字构建器
});
@override
@@ -25,23 +206,63 @@ class StatusBarWithIndicator extends StatelessWidget {
final totalGap = (itemCount - 1) * gap.rpx;
final itemWidth = (totalWidth - totalGap) / itemCount;
// 找到选中项的 index
// 找到选中项的 index 和对应的数据
final selectedIndex = showLabel.indexWhere((e) => e['key'] == selectKey);
final selectedItem = selectedIndex >= 0 ? showLabel[selectedIndex] : null;
final iconLeft = selectedIndex >= 0
? selectedIndex * (itemWidth + gap.rpx) + itemWidth / 2
: 0.0;
// 确定要显示的当前值文字
String displayValue = '';
if (showCurrentValue) {
if (currentValueText != null) {
displayValue = currentValueText!;
} else if (selectedItem != null) {
displayValue = selectedItem['name'] ?? '';
}
}
// 获取范围文字
String getRangeText(Map<String, dynamic> item) {
if (rangeTextBuilder != null) {
return rangeTextBuilder!(item) ?? '';
}
// 默认返回空字符串,需要外部传入范围数据
return item['range']?.toString() ?? '';
}
return SizedBox(
width: double.infinity,
child: Stack(
clipBehavior: Clip.none,
children: [
if (selectedIndex >= 0)
if (selectedIndex >= 0) ...[
// 如果显示当前值,在箭头上方添加文字
if (showCurrentValue && displayValue.isNotEmpty)
Positioned(
left: iconLeft,
top: -50.rpx,
child: Transform.translate(
offset: Offset(-45.rpx, 0),
child: Text(
displayValue,
style: TextStyle(
fontSize: AppConstants().small_an_text_fontSize,
color: themeController.currentColor.sc9,
fontWeight: FontWeight.w500,
),
),
),
),
// 箭头图片
Positioned(
left: iconLeft,
top: -20.rpx,
top: showCurrentValue ? -20.rpx : -20.rpx,
child: Transform.translate(
offset: Offset(-22.5.rpx, 0), // 图片宽度 45.rpx居中偏移
offset: Offset(-22.5.rpx, 0),
child: Container(
width: 45.rpx,
height: 76.rpx,
@@ -54,8 +275,11 @@ class StatusBarWithIndicator extends StatelessWidget {
),
),
),
],
// 条形图和文字标签
Padding(
padding: EdgeInsets.only(top: 50.rpx),
padding: EdgeInsets.only(top: showCurrentValue ? 70.rpx : 50.rpx),
child: Column(
children: [
// 条形段(带间距)
@@ -78,25 +302,46 @@ class StatusBarWithIndicator extends StatelessWidget {
}).toList(),
),
SizedBox(height: 12.rpx),
// 名称文字
// 名称文字和范围(每个下面显示对应的范围)
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: showLabel.asMap().entries.map((entry) {
int index = entry.key;
var item = entry.value;
return Container(
width: itemWidth,
margin: EdgeInsets.only(
left: index == 0 ? 0 : gap.rpx,
),
alignment: Alignment.center,
child: Text(
item['name'],
style: TextStyle(
fontSize: 24.rpx,
color: Colors.white,
return Expanded(
child: Container(
margin: EdgeInsets.only(
left: index == 0 ? 0 : gap.rpx,
),
child: Column(
children: [
// 名称文字
Text(
item['name'],
style: TextStyle(
fontSize: 24.rpx,
color: Colors.white,
),
textAlign: TextAlign.center,
),
// 范围文字(如果显示)
if (showRange)
Padding(
padding: EdgeInsets.only(top: 4.rpx),
child: Text(
"(" + getRangeText(item) + ")",
style: TextStyle(
fontSize: 20.rpx,
color: Colors.white.withOpacity(0.7),
),
textAlign: TextAlign.center,
),
),
],
),
textAlign: TextAlign.center,
),
);
}).toList(),