更新消息设置
This commit is contained in:
@@ -821,3 +821,338 @@ Future<void> showWeightPickerDialog(
|
||||
);
|
||||
}
|
||||
|
||||
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),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user