358 lines
14 KiB
Dart
358 lines
14 KiB
Dart
// 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,
|
||
required this.selectKey,
|
||
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
|
||
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'] ?? '';
|
||
}
|
||
}
|
||
|
||
// 获取范围文字
|
||
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 (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: showCurrentValue ? -20.rpx : -20.rpx,
|
||
child: Transform.translate(
|
||
offset: Offset(-22.5.rpx, 0),
|
||
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(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: showLabel.asMap().entries.map((entry) {
|
||
int index = entry.key;
|
||
var item = entry.value;
|
||
|
||
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,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}).toList(),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
});
|
||
}
|
||
}
|