113 lines
3.7 KiB
Dart
113 lines
3.7 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:vbvs_app/common/util/FitTool.dart';
|
||
|
||
class StatusBarWithIndicator extends StatelessWidget {
|
||
final int selectKey;
|
||
final List<Map<String, dynamic>> showLabel;
|
||
final IconData icon;
|
||
final double gap; // 每段之间的间距
|
||
|
||
const StatusBarWithIndicator({
|
||
super.key,
|
||
required this.selectKey,
|
||
required this.showLabel,
|
||
this.icon = Icons.favorite,
|
||
this.gap = 8.0, // 默认 8.rpx 间距
|
||
});
|
||
|
||
@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 iconLeft = selectedIndex >= 0
|
||
? selectedIndex * (itemWidth + gap.rpx) + itemWidth / 2
|
||
: 0.0;
|
||
|
||
return SizedBox(
|
||
width: double.infinity,
|
||
child: Stack(
|
||
clipBehavior: Clip.none,
|
||
children: [
|
||
if (selectedIndex >= 0)
|
||
Positioned(
|
||
left: iconLeft,
|
||
top: -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: 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(),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
});
|
||
}
|
||
}
|