Files
tuiche/lib/pages/person/select_time.dart
2025-12-05 17:37:01 +08:00

1159 lines
48 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:convert';
import 'dart:typed_data';
import 'package:ef/ef.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/pojo/city.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/language/AppLanguage.dart';
import 'package:vbvs_app/pages/common/selectDialog.dart';
// Future showDateSelectionDialog(BuildContext context,
// {required DateTime checkDate, Function? checkChange, String title = "生日"}) {
// ThemeController themeController = Get.find();
// List years = [], months = [], days = [];
// var days_select = [].obs;
// int day_len = 31;
// int year = DateTime.now().year;
// for (var i = 0; i < 100; i++) {
// years.insert(0, year - i);
// }
// for (var i = 1; i < 13; i++) {
// months.add(i);
// }
// for (var i = 1; i < 32; i++) {
// days.add(i);
// }
// int yearIndex = years.lastIndexOf(checkDate.year);
// int monthIndex = months.lastIndexOf(checkDate.month);
// day_len = DateTime.fromMillisecondsSinceEpoch(
// DateTime(years[yearIndex], months[monthIndex] + 1)
// .millisecondsSinceEpoch -
// 1000)
// .day;
// days_select.value = days.sublist(0, day_len);
// int dayIndex = days.lastIndexOf(checkDate.day);
// return showDialog(
// context: context,
// barrierDismissible: true, // 点击对话框外部可关闭
// builder: (BuildContext context) {
// return Stack(
// children: [
// Positioned(
// bottom: 0, // 控制弹窗距离顶部的位置
// left: 0,
// right: 0,
// child: Material(
// color: Colors.transparent,
// child: Dialog(
// backgroundColor: themeController.currentColor.sc17,
// insetPadding: EdgeInsets.zero,
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(0),
// ),
// child: Container(
// width: double.infinity,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.only(
// topLeft: Radius.circular(
// AppConstants().normal_container_radius),
// topRight: Radius.circular(
// AppConstants().normal_container_radius),
// bottomLeft: Radius.circular(0.rpx),
// bottomRight: Radius.circular(0.rpx),
// ),
// ),
// child: Column(
// mainAxisSize: MainAxisSize.min,
// crossAxisAlignment: CrossAxisAlignment.center,
// children: <Widget>[
// Container(
// color: themeController.currentColor.sc5,
// alignment: Alignment.centerLeft,
// height: 80.rpx,
// child: Padding(
// padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx),
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// InkWell(
// child: Text(
// "日期.取消".tr,
// style: TextStyle(
// fontFamily: 'Readex Pro',
// color: themeController.currentColor.sc3,
// letterSpacing: 0,
// fontSize:
// AppConstants().normal_text_fontSize),
// ),
// onTap: () {
// Get.back();
// },
// ),
// Text(
// "$title",
// style: TextStyle(
// fontFamily: 'Readex Pro',
// color: themeController.currentColor.sc3,
// letterSpacing: 0,
// fontSize:
// AppConstants().title_text_fontSize),
// ),
// // closeIconWhite,
// InkWell(
// child: Text(
// "日期.确定".tr,
// style: TextStyle(
// fontFamily: 'Readex Pro',
// color: themeController.currentColor.sc2,
// letterSpacing: 0,
// fontSize:
// AppConstants().normal_text_fontSize),
// ),
// onTap: () {
// checkChange?.call(DateTime(years[yearIndex],
// months[monthIndex], days[dayIndex]));
// Get.back();
// },
// )
// ],
// ),
// ),
// ),
// // Container(
// // height: 240.rpx,
// // margin: EdgeInsets.only(top: 60.rpx, bottom: 60.rpx),
// // padding: EdgeInsets.symmetric(horizontal: 30.rpx),
// // child: Row(
// // mainAxisAlignment: MainAxisAlignment.center, // ✅ 整体居中
// // crossAxisAlignment: CrossAxisAlignment.center,
// // children: [
// // Row(
// // children: [
// // SizedBox(
// // width: 120.rpx,
// // child: getOnePicker(context, years, yearIndex,
// // (d) {
// // yearIndex = d;
// // dayIndex = 0;
// // day_len =
// // DateTime.fromMillisecondsSinceEpoch(
// // DateTime(
// // years[yearIndex],
// // months[monthIndex] +
// // 1)
// // .millisecondsSinceEpoch -
// // 1000)
// // .day;
// // days_select.value =
// // days.sublist(0, day_len);
// // }, "".tr),
// // ),
// // ],
// // ),
// // SizedBox(width: 100.rpx),
// // // 月
// // Row(
// // children: [
// // SizedBox(
// // width: 80.rpx,
// // child: getOnePicker(
// // context, months, monthIndex, (d) {
// // monthIndex = d;
// // dayIndex = 0;
// // day_len =
// // DateTime.fromMillisecondsSinceEpoch(
// // DateTime(
// // years[yearIndex],
// // months[monthIndex] +
// // 1)
// // .millisecondsSinceEpoch -
// // 1000)
// // .day;
// // days_select.value =
// // days.sublist(0, day_len);
// // }, "".tr),
// // ),
// // ],
// // ),
// // SizedBox(width: 100.rpx),
// // Row(
// // children: [
// // SizedBox(
// // width: 80.rpx,
// // child: Obx(() {
// // return getOnePicker(
// // context, days_select, dayIndex, (d) {
// // dayIndex = d;
// // }, "".tr);
// // }),
// // ),
// // ],
// // ),
// // ],
// // ),
// // )
// //-----
// Container(
// height: 240.rpx,
// margin: EdgeInsets.only(top: 60.rpx, bottom: 60.rpx),
// padding: EdgeInsets.symmetric(horizontal: 30.rpx),
// child: Stack(
// children: [
// // ✅ 选中行背景色
// Positioned.fill(
// child: IgnorePointer(
// child: Center(
// child: Container(
// height: 90.rpx, // 对齐选中行高度
// margin: EdgeInsets.symmetric(
// horizontal: 10.rpx),
// decoration: BoxDecoration(
// color: themeController.currentColor.sc2,
// borderRadius:
// BorderRadius.circular(16.rpx),
// ),
// ),
// ),
// ),
// ),
// // ✅ 三列 Picker
// Row(
// mainAxisAlignment:
// MainAxisAlignment.center, // 整体居中
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// // 年
// SizedBox(
// width: 120.rpx,
// child: getOnePicker(context, years, yearIndex,
// (d) {
// yearIndex = d;
// dayIndex = 0;
// day_len =
// DateTime.fromMillisecondsSinceEpoch(
// DateTime(
// years[yearIndex],
// months[monthIndex] +
// 1)
// .millisecondsSinceEpoch -
// 1000)
// .day;
// days_select.value =
// days.sublist(0, day_len);
// }, "".tr),
// ),
// SizedBox(width: 100.rpx),
// // 月
// SizedBox(
// width: 80.rpx,
// child: getOnePicker(
// context, months, monthIndex, (d) {
// monthIndex = d;
// dayIndex = 0;
// day_len =
// DateTime.fromMillisecondsSinceEpoch(
// DateTime(
// years[yearIndex],
// months[monthIndex] +
// 1)
// .millisecondsSinceEpoch -
// 1000)
// .day;
// days_select.value =
// days.sublist(0, day_len);
// }, "".tr),
// ),
// SizedBox(width: 100.rpx),
// // 日
// SizedBox(
// width: 80.rpx,
// child: Obx(() {
// return getOnePicker(
// context, days_select, dayIndex, (d) {
// dayIndex = d;
// }, "".tr);
// }),
// ),
// ],
// ),
// ],
// ),
// ),
// ],
// ),
// ),
// ),
// ),
// ),
// ],
// );
// },
// );
// }
Future showDateSelectionDialog(BuildContext context,
{required DateTime checkDate,
Function? checkChange,
String title = "选择生日"}) {
ThemeController themeController = Get.find();
final bool isEn = Get.locale?.languageCode.startsWith('en') ?? false;
Color checkColor = stringToColor("#D3B684");
final List<int> years = List.generate(100, (i) => DateTime.now().year - i)
..sort();
final List<int> months = List.generate(12, (i) => i + 1);
final List<int> days = List.generate(31, (i) => i + 1);
final RxList<int> daysSelect = <int>[].obs;
final RxInt yearIndex = years.indexOf(checkDate.year).obs;
final RxInt monthIndex = months.indexOf(checkDate.month).obs;
final RxInt dayIndex = days.indexOf(checkDate.day).obs;
void updateDays() {
final int daysInMonth =
DateTime(years[yearIndex.value], months[monthIndex.value] + 1, 0).day;
daysSelect.value = days.sublist(0, daysInMonth);
if (dayIndex.value >= daysInMonth) {
dayIndex.value = daysInMonth - 1;
}
}
updateDays();
return showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Stack(
children: [
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Material(
color: Colors.transparent,
child: Dialog(
backgroundColor: themeController.currentColor.sc17,
insetPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container(
width: double.infinity,
padding: EdgeInsets.fromLTRB(30.rpx, 10.rpx, 30.rpx, 90.rpx),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.zero,
onTap: () => Navigator.of(context).pop(),
child: Container(
width: 110.rpx,
height: 60.rpx,
alignment: Alignment.center,
child: Text("取消".tr,
style: TextStyle(
fontSize: 30.rpx, color: Colors.white)),
),
),
Text(
title,
style: TextStyle(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
fontSize: 30.rpx,
),
),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.zero,
onTap: () {
final selectedDate = DateTime(
years[yearIndex.value],
months[monthIndex.value],
daysSelect[dayIndex.value],
);
checkChange?.call(selectedDate);
Get.back();
},
child: Container(
width: 110.rpx,
height: 60.rpx,
alignment: Alignment.center,
child: Text("确定".tr,
style: TextStyle(
fontSize: 30.rpx,
color: themeController.currentColor.sc2,
)),
),
),
],
),
SizedBox(height: 20.rpx),
Stack(
children: [
Positioned.fill(
child: IgnorePointer(
child: Center(
child: Container(
height: 90.rpx,
margin:
EdgeInsets.symmetric(horizontal: 70.rpx),
decoration: BoxDecoration(
color: themeController.currentColor.sc2,
borderRadius: BorderRadius.circular(16.rpx),
),
),
),
),
),
SizedBox(
height: 240.rpx,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 95.rpx),
child: Row(
children: isEn
? [
Expanded(
child: getOnePickers(
context,
months,
monthIndex,
isMonthName: true,
onChanged: (_) => updateDays(),
),
),
Expanded(
child: getOnePickers(
context,
daysSelect,
dayIndex,
),
),
Expanded(
child: getOnePickers(
context,
years,
yearIndex,
onChanged: (_) => updateDays(),
),
),
]
: [
Expanded(
child: getOnePickers(
context,
years,
yearIndex,
unit: "",
onChanged: (_) => updateDays(),
),
),
Expanded(
child: getOnePickers(
context,
months,
monthIndex,
unit: "",
onChanged: (_) => updateDays(),
),
),
Expanded(
child: getOnePickers(
context,
daysSelect,
dayIndex,
unit: "",
),
),
],
),
),
),
],
),
],
),
),
),
),
),
],
);
},
);
}
TextStyle _unitStyle(BuildContext context) {
return TextStyle(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
fontSize: 30.rpx,
letterSpacing: 0,
);
}
getOnePicker(BuildContext context, List arr, int checkIndex,
Function onSelectedItemChanged, String unit,
{bool looping = false}) {
ThemeController themeController = Get.find();
return CupertinoPicker(
key: UniqueKey(),
useMagnifier: false,
itemExtent: 80.rpx,
magnification: 1,
diameterRatio: 3,
squeeze: 1,
looping: looping,
scrollController: FixedExtentScrollController(initialItem: checkIndex),
selectionOverlay: Container(), // 不要默认选中遮罩
onSelectedItemChanged: (int value) {
onSelectedItemChanged.call(value);
},
children: List.generate(arr.length, (index) {
return Container(
alignment: Alignment.center,
child: Text(
"${arr[index]}$unit", // ✅ 每项都带单位
style: TextStyle(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
fontSize: 30.rpx,
),
),
);
}),
);
}
Future<void> showHeightPickerDialog(
BuildContext context, {
required int initialHeight, // 初始身高单位cm
required Function(int selectedHeight) onConfirm,
String title = "选择身高",
}) async {
List<int> heights = List.generate(101, (index) => 120 + index); // 120~220cm
int selectedIndex = heights.indexOf(initialHeight);
// int tempIndex = selectedIndex;
final RxInt tempIndex = RxInt(selectedIndex); // ✅ 改为 RxInt
ThemeController themeController = Get.find();
await showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Stack(
children: [
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Material(
color: Colors.transparent,
child: Dialog(
backgroundColor: themeController.currentColor.sc17,
insetPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container(
padding: EdgeInsets.fromLTRB(0.rpx, 0.rpx, 0.rpx, 90.rpx),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding:
EdgeInsets.fromLTRB(30.rpx, 0.rpx, 30.rpx, 0.rpx),
color: themeController.currentColor.sc5,
height: 80.rpx,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(top: 0),
onTap: () {
Get.back();
},
child: Container(
alignment: Alignment.center,
width: 110.rpx,
height: 60.rpx,
child: Text(
"取消".tr,
style: TextStyle(
fontSize: 30.rpx,
color: Colors.white,
),
),
)),
Text(title,
style: TextStyle(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
fontSize: 30.rpx,
)),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(top: 0),
onTap: () {
onConfirm(
heights[tempIndex.value]); // ✅ 使用 .value
Get.back();
},
child: Container(
alignment: Alignment.center,
width: 110.rpx,
height: 60.rpx,
child: Text(
"确定".tr,
style: TextStyle(
fontSize: 30.rpx,
color: themeController.currentColor.sc2,
),
),
)),
],
),
),
SizedBox(height: 20.rpx),
Stack(
children: [
Positioned.fill(
child: IgnorePointer(
child: Center(
child: Container(
height: 90.rpx,
margin:
EdgeInsets.symmetric(horizontal: 95.rpx),
decoration: BoxDecoration(
color: themeController.currentColor.sc2,
borderRadius: BorderRadius.circular(16.rpx),
),
),
),
),
),
SizedBox(
height: 240.rpx,
child: getOnePickers(
context,
heights,
tempIndex, // ✅ 传入 RxInt
unit: "cm",
),
),
],
),
],
),
),
),
),
),
],
);
},
);
}
Future<void> showWeightPickerDialog(
BuildContext context, {
required String initialWeight, // 初始体重单位kg
required Function(int selectedWeight) onConfirm,
String title = "选择体重",
}) async {
List<int> weights = List.generate(151, (index) => 30 + index); // 30~180kg
int selectedIndex = weights.indexOf(int.tryParse(initialWeight) ?? 50);
final RxInt tempIndex = RxInt(selectedIndex); // ✅ 改为 RxInt
ThemeController themeController = Get.find();
await showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Stack(
children: [
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Material(
color: Colors.transparent,
child: Dialog(
backgroundColor: themeController.currentColor.sc17,
insetPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container(
padding: EdgeInsets.fromLTRB(0.rpx, 0.rpx, 0.rpx, 90.rpx),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// 标题 + 按钮
Container(
padding:
EdgeInsets.fromLTRB(30.rpx, 0.rpx, 30.rpx, 0.rpx),
color: themeController.currentColor.sc5,
height: 80.rpx,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(top: 0),
onTap: () {
Navigator.of(context).pop();
},
child: Container(
alignment: Alignment.center,
width: 110.rpx,
height: 60.rpx,
child: Text(
"取消".tr,
style: TextStyle(
fontSize: 30.rpx,
color: Colors.white,
),
),
)),
Text(title.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
fontSize: 30.rpx,
)),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(top: 0),
onTap: () {
onConfirm(
weights[tempIndex.value]); // ✅ 回调返回选中值
Get.back();
},
child: Container(
alignment: Alignment.center,
width: 110.rpx,
height: 60.rpx,
child: Text(
"确定".tr,
style: TextStyle(
fontSize: 30.rpx,
color: themeController.currentColor.sc2,
),
),
)),
],
),
),
SizedBox(height: 20.rpx),
Stack(
children: [
Positioned.fill(
child: IgnorePointer(
child: Center(
child: Container(
height: 90.rpx,
margin:
EdgeInsets.symmetric(horizontal: 95.rpx),
decoration: BoxDecoration(
color: themeController.currentColor.sc2,
borderRadius: BorderRadius.circular(16.rpx),
),
),
),
),
),
SizedBox(
height: 240.rpx,
child: getOnePickers(
context,
weights,
tempIndex, // ✅ 传入 RxInt
unit: "kg",
),
),
],
),
],
),
),
),
),
),
],
);
},
);
}
Future<void> showScorePickerDialog(
BuildContext context, {
required int initialHeight,
required Function(int selectedHeight) onConfirm,
String title = "选择分数",
String unit = "", // 单位(可选)
int min = 0, // ✅ 新增:最小值
int max = 100, // ✅ 新增:最大值
}) async {
/// 生成范围min ~ max
List<int> heights = List.generate(max - min + 1, (index) => min + index);
/// 确保初始值在范围内
if (initialHeight < min) initialHeight = min;
if (initialHeight > max) initialHeight = max;
int selectedIndex = heights.indexOf(initialHeight);
final RxInt tempIndex = RxInt(selectedIndex);
ThemeController themeController = Get.find();
await showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Stack(
children: [
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Material(
color: Colors.transparent,
child: Dialog(
backgroundColor: themeController.currentColor.sc17,
insetPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container(
padding: EdgeInsets.fromLTRB(0.rpx, 0.rpx, 0.rpx, 90.rpx),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// ------- 顶部标题区域 -------
Container(
padding:
EdgeInsets.fromLTRB(30.rpx, 0.rpx, 30.rpx, 0.rpx),
color: themeController.currentColor.sc5,
height: 80.rpx,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(top: 0),
onTap: () {
Get.back();
},
child: Container(
alignment: Alignment.center,
width: 110.rpx,
height: 60.rpx,
child: Text(
"取消".tr,
style: TextStyle(
fontSize: 30.rpx,
color: Colors.white,
),
),
),
),
Text(
title,
style: TextStyle(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
fontSize: 30.rpx,
),
),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(top: 0),
onTap: () {
onConfirm(heights[tempIndex.value]);
Get.back();
},
child: Container(
alignment: Alignment.center,
width: 110.rpx,
height: 60.rpx,
child: Text(
"确定".tr,
style: TextStyle(
fontSize: 30.rpx,
color: themeController.currentColor.sc2,
),
),
),
),
],
),
),
SizedBox(height: 20.rpx),
// -------- 中间选择器 --------
Stack(
children: [
Positioned.fill(
child: IgnorePointer(
child: Center(
child: Container(
height: 90.rpx,
margin:
EdgeInsets.symmetric(horizontal: 95.rpx),
decoration: BoxDecoration(
color: themeController.currentColor.sc2,
borderRadius: BorderRadius.circular(16.rpx),
),
),
),
),
),
SizedBox(
height: 240.rpx,
child: getOnePickers(
context,
heights,
tempIndex,
unit: unit, // 使用传入的单位
),
),
],
),
],
),
),
),
),
),
],
);
},
);
}
Future<void> showIntervalPickerDialog(
BuildContext context, {
required int initialValue,
required Function(int selectedValue) onConfirm,
List<int> options = const [], // ✅ 可选值数组(优先级最高)
int min = 0, // 若没有 options则使用 min/max
int max = 100,
int type = 2, // 1=秒2=分钟默认3=小时
String unit = "分钟/次",
String title = "选择间隔",
}) async {
ThemeController themeController = Get.find();
/// ------------------------------------------
/// 计算实际数据源:优先使用 options
/// ------------------------------------------
List<int> values;
if (options.isNotEmpty) {
values = [...options];
} else {
values = List.generate(max - min + 1, (index) => min + index);
}
/// ------------------------------------------
/// 显示转换函数
/// ------------------------------------------
String formatValue(int raw) {
double result;
switch (type) {
case 1: // 秒
result = raw.toDouble();
return "${result.toInt()}秒/次";
case 2: // 分钟
result = raw / 60.0;
break;
case 3: // 小时
result = raw / 3600.0;
break;
default:
result = raw.toDouble();
}
/// 去掉多余的小数,例如 1.0 → 1
String text =
result % 1 == 0 ? result.toInt().toString() : result.toStringAsFixed(1);
return "$text$unit";
}
/// ------------------------------------------
/// 初始 index
/// ------------------------------------------
int initialIndex = values.indexOf(initialValue);
if (initialIndex < 0) initialIndex = 0;
final RxInt tempIndex = RxInt(initialIndex);
await showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Stack(
children: [
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Material(
color: Colors.transparent,
child: Dialog(
backgroundColor: themeController.currentColor.sc17,
insetPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container(
padding: EdgeInsets.fromLTRB(0.rpx, 0.rpx, 0.rpx, 90.rpx),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
/// ---------------- 顶部标题 ----------------
Container(
padding:
EdgeInsets.fromLTRB(30.rpx, 0.rpx, 30.rpx, 0.rpx),
color: themeController.currentColor.sc5,
height: 80.rpx,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: () => Get.back(),
padding: EdgeInsets.all(0),
child: Container(
alignment: Alignment.center,
width: 110.rpx,
height: 60.rpx,
child: Text(
"取消".tr,
style: TextStyle(
fontSize: 30.rpx,
color: Colors.white,
),
),
),
),
Text(
title,
style: TextStyle(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
fontSize: 30.rpx,
),
),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: () {
onConfirm(values[tempIndex.value]); // 返回原始秒数
Get.back();
},
padding: EdgeInsets.all(0),
child: Container(
alignment: Alignment.center,
width: 110.rpx,
height: 60.rpx,
child: Text(
"确定".tr,
style: TextStyle(
fontSize: 30.rpx,
color: themeController.currentColor.sc2,
),
),
),
),
],
),
),
SizedBox(height: 20.rpx),
/// ---------------- 中间选择器 ----------------
Stack(
children: [
Positioned.fill(
child: IgnorePointer(
child: Center(
child: Container(
height: 90.rpx,
margin:
EdgeInsets.symmetric(horizontal: 95.rpx),
decoration: BoxDecoration(
color: themeController.currentColor.sc2,
borderRadius: BorderRadius.circular(16.rpx),
),
),
),
),
),
SizedBox(
height: 240.rpx,
child: getOnePickers(
context,
values,
tempIndex,
/// → 替换显示文本(核心)
customDisplay: (val) => formatValue(val),
),
),
],
),
],
),
),
),
),
),
],
);
},
);
}