Files
tuiche/lib/pages/common/selectDialog.dart
2025-07-01 21:01:28 +08:00

1447 lines
55 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 'package:ef/ef.dart';
import 'package:flutter/cupertino.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';
import 'package:vbvs_app/component/base/SleepCalendarWidget.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/controller/device/device_calibration_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
getOnePicker(BuildContext context, List arr, int checkIndex,
Function onSelectedItemChanged,
{bool looping = false, String unit = ''}) {
ThemeController themeController = Get.find();
return CupertinoPicker(
key: UniqueKey(),
useMagnifier: false,
itemExtent: 90.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) {
bool isSelected = index == checkIndex;
Color textColor = isSelected ? Color(0XFF011D33) : Color(0xFF9AA0B3);
return Container(
alignment: Alignment.center,
width: 400.rpx,
// decoration: BoxDecoration(
// border: Border(
// bottom: index != arr.length
// ? BorderSide(color: stringToColor("#8D95B0"))
// : BorderSide.none,
// ),
// ),
child: Text("${arr[index]}$unit",
style: TextStyle(
fontFamily: 'Readex Pro',
color: textColor,
letterSpacing: 0,
fontSize: 30.rpx)),
);
})
],
);
}
//支持选中时文字变色
getOnePickers(
BuildContext context,
List arr,
RxInt selectedIndex, {
String unit = '',
bool looping = false,
void Function(int)? onChanged,
}) {
ThemeController themeController = Get.find();
return Obx(() {
return CupertinoPicker.builder(
itemExtent: 90.rpx,
useMagnifier: false,
magnification: 1,
diameterRatio: 3,
squeeze: 1,
// looping: looping,
scrollController:
FixedExtentScrollController(initialItem: selectedIndex.value),
selectionOverlay: Container(),
onSelectedItemChanged: (int index) {
selectedIndex.value = index;
},
childCount: arr.length,
itemBuilder: (context, index) {
bool isSelected = index == selectedIndex.value;
return Center(
child: Text(
"${arr[index]}$unit",
style: TextStyle(
fontFamily: 'Readex Pro',
color: isSelected
? const Color(0xFF011D33) // ✅ 选中项颜色
: Color(0xFF9AA0B3), // 未选中颜色
fontSize: 30.rpx,
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
),
),
);
},
);
});
}
Future showDateSelectionDialog(BuildContext context,
{required DateTime checkDate,
Function? checkChange,
String title = "选择生日"}) {
ThemeController themeController = Get.find();
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: const Color(0xFF003058),
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: 100.rpx,
height: 60.rpx,
alignment: Alignment.center,
child: Text("取消",
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: 100.rpx,
height: 60.rpx,
alignment: Alignment.center,
child: Text("确定",
style: TextStyle(
fontSize: 30.rpx, color: stringToColor("#84F5FF"))),
),
),
],
),
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: const Color(0xFF84F5FF),
borderRadius: BorderRadius.circular(16.rpx),
),
),
),
),
),
SizedBox(
height: 240.rpx,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 95.rpx),
child: Row(
children: [
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: "",
),
),
],
),
),
),
],
),
],
),
),
),
),
),
],
);
},
);
}
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: Color(0xFF003058),
insetPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container(
padding: EdgeInsets.fromLTRB(30.rpx, 10.rpx, 30.rpx, 90.rpx),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// 标题 + 按钮
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: 100.rpx,
height: 60.rpx,
child: Text(
"取消",
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(
weights[tempIndex.value]); // ✅ 回调返回选中值
Get.back();
},
child: Container(
alignment: Alignment.center,
width: 100.rpx,
height: 60.rpx,
child: Text(
"确定",
style: TextStyle(
fontSize: 30.rpx,
color: stringToColor("#84F5FF"),
),
),
)),
],
),
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: Color(0xFF84F5FF),
borderRadius: BorderRadius.circular(16.rpx),
),
),
),
),
),
SizedBox(
height: 240.rpx,
child: getOnePickers(
context,
weights,
tempIndex, // ✅ 传入 RxInt
unit: "kg",
),
),
],
),
],
),
),
),
),
),
],
);
},
);
}
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: Color(0xFF003058),
insetPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container(
padding: EdgeInsets.fromLTRB(30.rpx, 10.rpx, 30.rpx, 90.rpx),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
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: 100.rpx,
height: 60.rpx,
child: Text(
"取消",
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: 100.rpx,
height: 60.rpx,
child: Text(
"确定",
style: TextStyle(
fontSize: 30.rpx,
color: stringToColor("#84F5FF"),
),
),
)),
],
),
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: Color(0xFF84F5FF),
borderRadius: BorderRadius.circular(16.rpx),
),
),
),
),
),
SizedBox(
height: 240.rpx,
child: getOnePickers(
context,
heights,
tempIndex, // ✅ 传入 RxInt
unit: "cm",
),
),
],
),
],
),
),
),
),
),
],
);
},
);
}
// Future showDayTimeSelectionDialog(BuildContext context,
// {required List<int> dayTimeArr, Function? checkChange, String title = ""}) {
// ThemeController themeController = Get.find();
// final hours = List.generate(24, (i) => i);
// final minutes = List.generate(60, (i) => i);
// final RxInt hoursIndex = RxInt(hours.indexOf(dayTimeArr[0]));
// final RxInt minutesIndex = RxInt(minutes.indexOf(dayTimeArr[1]));
// 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: stringToColor("#182B7C"),
// 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: [
// Text(
// title,
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Readex Pro',
// color: themeController.currentColor.sc3,
// fontSize: 30.rpx,
// ),
// ),
// closeIconWhite,
// ],
// ),
// Container(
// height: 240.rpx,
// margin: EdgeInsets.only(top: 60.rpx, bottom: 60.rpx),
// padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx),
// child: Row(
// children: [
// Expanded(
// child: Padding(
// padding:
// EdgeInsets.symmetric(horizontal: 10.rpx),
// child: getOnePickers(context, hours, hoursIndex,
// unit: ''),
// ),
// ),
// Text(
// "时",
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Readex Pro',
// color: themeController.currentColor.sc3,
// fontSize: 30.rpx,
// ),
// ),
// Expanded(
// child: Padding(
// padding:
// EdgeInsets.symmetric(horizontal: 10.rpx),
// child: getOnePickers(
// context, minutes, minutesIndex,
// unit: ''),
// ),
// ),
// Text(
// "分",
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Readex Pro',
// color: themeController.currentColor.sc3,
// fontSize: 30.rpx,
// ),
// ),
// ],
// ),
// ),
// InkWell(
// onTap: () {
// checkChange?.call([
// hours[hoursIndex.value],
// minutes[minutesIndex.value]
// ]);
// Get.back();
// },
// child: Container(
// height: 68.rpx,
// alignment: Alignment.center,
// decoration: BoxDecoration(
// color: stringToColor("#D3B684"),
// borderRadius: BorderRadius.circular(10.rpx),
// ),
// child: Text(
// "确定",
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Readex Pro',
// color: themeController.currentColor.sc3,
// fontSize: 30.rpx,
// ),
// ),
// ),
// )
// ],
// ),
// ),
// ),
// ),
// ),
// ],
// );
// },
// );
// }
Future showDayTimeSelectionDialog(
BuildContext context, {
required List<int> dayTimeArr,
Function(List<int>)? checkChange,
String title = "选择时间",
}) {
ThemeController themeController = Get.find();
Color checkColor = stringToColor("#D3B684");
final List<int> hours = List.generate(24, (i) => i);
final List<int> minutes = List.generate(60, (i) => i);
final RxInt hoursIndex = hours.indexOf(dayTimeArr[0]).obs;
final RxInt minutesIndex = minutes.indexOf(dayTimeArr[1]).obs;
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: const Color(0xFF003058),
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: 100.rpx,
height: 60.rpx,
alignment: Alignment.center,
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.zero,
onTap: () {
checkChange?.call([
hours[hoursIndex.value],
minutes[minutesIndex.value],
]);
Get.back();
},
child: Container(
width: 100.rpx,
height: 60.rpx,
alignment: Alignment.center,
child: Text("确定".tr,
style: TextStyle(
fontSize: 30.rpx, color: stringToColor("#84F5FF"))),
),
),
],
),
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: const Color(0xFF84F5FF),
borderRadius: BorderRadius.circular(16.rpx),
),
),
),
),
),
SizedBox(
height: 240.rpx,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 95.rpx),
child: Row(
children: [
Expanded(
child: getOnePickers(
context,
hours,
hoursIndex,
unit: "".tr,
),
),
Expanded(
child: getOnePickers(
context,
minutes,
minutesIndex,
unit: "".tr,
),
),
],
),
),
),
],
),
],
),
),
),
),
),
],
);
},
);
}
Future showOneSelectionDialog(
BuildContext context, {
required List arr,
int checkIndex = 0,
Function? checkChange,
String title = "选择性别",
}) {
ThemeController themeController = Get.find();
Color checkColor = stringToColor("#D3B684");
final RxInt selectedIndex = checkIndex.obs; // ✅ 用RxInt变量监听选中项
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: const Color(0xFF003058),
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,
children: <Widget>[
// 顶部标题 + 按钮
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.zero,
onTap: () => Get.back(),
child: Container(
alignment: Alignment.center,
width: 100.rpx,
height: 60.rpx,
child: Text("取消".tr,
style: TextStyle(
fontSize: 30.rpx, color: Colors.white)),
),
),
Text(title.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 30.rpx,
)),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.zero,
onTap: () {
checkChange?.call(selectedIndex.value);
Get.back();
},
child: Container(
alignment: Alignment.center,
width: 100.rpx,
height: 60.rpx,
child: Text("确定".tr,
style: TextStyle(
fontSize: 30.rpx, color: stringToColor("#84F5FF"))),
),
),
],
),
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: const Color(0xFF84F5FF),
borderRadius: BorderRadius.circular(16.rpx),
),
),
),
),
),
Container(
height: 240.rpx,
margin: EdgeInsets.only(
top: 60.rpx,
bottom: 60.rpx,
left: 30.rpx,
right: 30.rpx),
child: getOnePickers(
context,
arr,
selectedIndex,
unit: '',
),
),
],
),
],
),
),
),
),
),
],
);
},
);
}
enum ConfirmDialogIcon {
none,
danger,
success,
warn;
get uname {
String v = "";
switch (this) {
case ConfirmDialogIcon.danger:
v = "danger";
break;
case ConfirmDialogIcon.success:
v = "success";
break;
case ConfirmDialogIcon.warn:
v = "warn";
break;
case ConfirmDialogIcon.none:
v = "";
break;
}
return v;
}
}
Future showCustomConfirmDialog(BuildContext context, String name,
{String btnName = "确定",
ConfirmDialogIcon icon = ConfirmDialogIcon.warn}) async {
ThemeController themeController = Get.find();
return showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Container(
width: 660.rpx,
padding: EdgeInsets.fromLTRB(16, 0, 16, 16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment.centerRight,
child: closeIcon,
),
SizedBox(height: 60.rpx),
if ("${icon.uname}".isNotEmpty)
Center(
child: Container(
margin: EdgeInsets.only(bottom: 39.rpx),
width: 50.rpx,
height: 50.rpx,
child: Image.asset("assets/images/toast/${icon.uname}.png"),
),
),
Center(
child: Text(
'${name}',
style: TextStyle(fontSize: 16),
),
),
SizedBox(height: 20.rpx),
Container(
margin: EdgeInsets.only(top: 50.rpx, bottom: 40.rpx),
alignment: Alignment.center,
child: InkWell(
onTap: () {
Get.back(result: "confirm");
},
child: Container(
width: 260.rpx,
height: 60.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: stringToColor("#D3B684")),
child: Text(
'$btnName',
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize: 30.rpx),
),
),
),
)
],
),
),
);
},
);
}
Future showCustomConfirmAndCancelDialog(BuildContext context, String name,
{String confirmName = "确定",
String cancelName = "取消",
ConfirmDialogIcon icon = ConfirmDialogIcon.warn}) async {
ThemeController themeController = Get.find();
return showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Container(
width: 660.rpx,
padding: EdgeInsets.fromLTRB(16, 0, 16, 16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment.centerRight,
child: closeIcon,
),
SizedBox(height: 40.rpx),
if ("${icon.uname}".isNotEmpty)
Center(
child: Container(
margin: EdgeInsets.only(bottom: 39.rpx),
width: 50.rpx,
height: 50.rpx,
child: Image.asset("assets/images/toast/${icon.uname}.png"),
),
),
Center(
child: Text(
'${name}',
style: TextStyle(fontSize: 16),
),
),
SizedBox(height: 20.rpx),
Container(
margin: EdgeInsets.only(top: 50.rpx, bottom: 40.rpx),
alignment: Alignment.center,
child: InkWell(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
Get.back(result: "cancel");
},
child: Container(
width: 200.rpx,
height: 60.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
border: Border.all(color: Colors.black12)),
child: Text(
'$cancelName',
style:
TextStyle(color: Colors.black, fontSize: 30.rpx),
),
),
),
SizedBox(
width: 80.rpx,
),
InkWell(
onTap: () {
Get.back(result: "confirm");
},
child: Container(
width: 200.rpx,
height: 60.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: stringToColor("#D3B684")),
child: Text(
'$confirmName',
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize: 30.rpx),
),
),
)
],
)),
)
],
),
),
);
},
);
}
//权限说明弹窗
void showPermissionInfoDialog(BuildContext context, List data) {
ThemeController themeController = Get.find();
showDialog(
context: context,
barrierDismissible: false, // 点击对话框外部可关闭
builder: (BuildContext context) {
return Stack(
children: [
Positioned(
top: 30.rpx, // 控制弹窗距离顶部的位置
left: 0,
right: 0,
child: Material(
color: Colors.transparent,
child: Dialog(
backgroundColor: themeController.currentColor.sc3,
insetPadding: EdgeInsets.fromLTRB(0, 0, 0, 0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Container(
constraints: BoxConstraints(maxHeight: 500.rpx),
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
...List.generate(data.length, (index) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${data[index][0]}",
style: TextStyle(
fontSize: 30.rpx,
color: stringToColor("#333333"),
),
),
SizedBox(
height: 4.rpx,
),
Text(
"${data[index][1]}",
style: TextStyle(
fontSize: 26.rpx,
color: stringToColor("#A4AABC"),
),
),
if (index != data.length - 1)
SizedBox(
height: 18.rpx,
),
],
);
}),
],
),
),
),
),
),
),
],
);
},
);
}
void showProgressDialog(
BuildContext context,
ValueNotifier<double> progressNotifier,
ValueNotifier<bool> failureNotifier,
) {
ThemeController themeController = Get.find();
DeviceCalibrationController deviceCalibrationController = Get.find();
showDialog(
context: context,
barrierDismissible: false, // 点击对话框外部不可关闭
builder: (BuildContext dialogContext) {
return Stack(
children: [
Positioned(
top: MediaQuery.of(context).size.height * 0.4,
left: MediaQuery.of(context).size.width * 0.05,
right: MediaQuery.of(context).size.width * 0.05,
child: Material(
color: Colors.transparent,
child: Dialog(
backgroundColor: Colors.transparent,
insetPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
child: ValueListenableBuilder<double>(
valueListenable: progressNotifier,
builder: (context, progress, _) {
return ValueListenableBuilder<bool>(
valueListenable: failureNotifier,
builder: (context, isFailure, __) {
// 关闭弹窗的逻辑
if (isFailure) {
// 延迟关闭弹窗和提示错误
Future.delayed(Duration(milliseconds: 300), () {
if (Navigator.canPop(dialogContext)) {
Navigator.of(dialogContext).pop();
}
});
} else if (progress >= 100) {
// 延迟关闭弹窗和提示成功(可选)
Future.delayed(Duration(milliseconds: 300), () {
if (Navigator.canPop(dialogContext)) {
Navigator.of(dialogContext).pop();
}
});
}
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
isFailure
? '失败'.tr
: '${(progress).toStringAsFixed(0)}%',
style: TextStyle(
fontSize: 26.rpx,
color: isFailure
? Colors.red
: themeController.currentColor.sc3,
),
),
SizedBox(height: 40.rpx),
Stack(
children: [
Container(
width: double.infinity,
height: 21.rpx,
decoration: BoxDecoration(
color: stringToColor("#D9D9D9"),
borderRadius: BorderRadius.circular(
AppConstants().button_container_radius,
),
),
),
Container(
width: progress /
100 *
MediaQuery.of(context).size.width *
0.8,
height: 21.rpx,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: isFailure
? [themeController.currentColor.sc9]
: [
themeController
.currentColor.sc2,
themeController
.currentColor.sc2,
],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
borderRadius: BorderRadius.circular(
AppConstants().button_container_radius,
),
),
),
],
),
],
);
},
);
},
),
),
),
),
),
],
);
},
);
}
void showSleepCalendarBottomSheet({
required BuildContext context,
int? timestamp,
int? type = 1, // 新增参数默认值为1
required void Function(DateTime selectedDate) onDateSelected,
}) {
showModalBottomSheet(
context: context,
isScrollControlled: false,
backgroundColor: Colors.transparent,
builder: (context) {
return Container(
decoration: BoxDecoration(
color: const Color(0xFF242835),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.rpx),
topRight: Radius.circular(20.rpx),
),
),
child: SleepCalendarWidget(
timestamp: timestamp,
type: type, // 传递类型给子组件
onDateSelected: onDateSelected,
// highlightColor: Colors.green,
),
);
},
);
}
Future showCustomConfirmOfWebViewDialog(
BuildContext context, String name, String webviewUrl,
{String btnName = "确定",
bool showCancel = false,
String cancelName = "取消",
ConfirmDialogIcon icon = ConfirmDialogIcon.warn}) async {
return showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Dialog(
insetPadding: EdgeInsets.all(0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Container(
width: 640.rpx,
padding: EdgeInsets.fromLTRB(22.rpx, 0, 20.rpx, 10.rpx),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment.centerRight,
child: closeIcon,
),
SizedBox(height: 40.rpx),
// Container(
// height: MediaQuery.of(context).size.height * 0.4,
// child: Shopping(
// url: webviewUrl,
// ),
// ),
SizedBox(height: 20.rpx),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (showCancel)
Container(
margin: EdgeInsets.only(
top: 50.rpx, bottom: 40.rpx, right: 100.rpx),
alignment: Alignment.center,
child: InkWell(
onTap: () {
Get.back();
},
child: Container(
width: 200.rpx,
height: 60.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
border: Border.all(color: Colors.black12)),
child: Text(
'$cancelName',
style: TextStyle(
color: Colors.black, fontSize: 30.rpx),
),
),
),
),
Container(
margin: EdgeInsets.only(top: 50.rpx, bottom: 40.rpx),
alignment: Alignment.center,
child: InkWell(
onTap: () {
Get.back(result: "confirm");
},
child: Container(
width: 200.rpx,
height: 60.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: stringToColor("#D3B684")),
child: Text(
'$btnName',
style:
TextStyle(color: Colors.white, fontSize: 30.rpx),
),
),
),
)
],
)
],
),
),
);
},
);
}