2024-03-25 14:16:00 +08:00
|
|
|
|
import 'package:flutter/cupertino.dart';
|
2024-03-19 11:09:07 +08:00
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:get/get.dart';
|
2024-04-01 11:38:10 +08:00
|
|
|
|
import 'package:sk_base_mobile/app_theme.dart';
|
2024-03-26 11:35:39 +08:00
|
|
|
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
2024-04-01 08:41:52 +08:00
|
|
|
|
import 'package:sk_base_mobile/widgets/core/sk_bottomsheet_picker.dart';
|
2024-03-19 11:09:07 +08:00
|
|
|
|
|
|
|
|
|
class ModalUtil {
|
2024-04-07 17:32:46 +08:00
|
|
|
|
static Future<bool> alert(
|
|
|
|
|
{String? title,
|
|
|
|
|
String? contentText,
|
|
|
|
|
String? confirmText,
|
2024-04-15 10:59:12 +08:00
|
|
|
|
String? cancelText,
|
2024-04-07 17:32:46 +08:00
|
|
|
|
Widget? content,
|
|
|
|
|
VoidCallback? onConfirm,
|
2024-04-15 10:59:12 +08:00
|
|
|
|
VoidCallback? onCancel,
|
2024-04-07 17:32:46 +08:00
|
|
|
|
Widget Function(BuildContext)? builder,
|
|
|
|
|
EdgeInsetsGeometry? contentPadding,
|
|
|
|
|
bool showActions = true,
|
|
|
|
|
bool barrierDismissible = true,
|
|
|
|
|
bool showCancel = true}) async {
|
2024-03-19 11:09:07 +08:00
|
|
|
|
bool confirmed = false;
|
|
|
|
|
await showDialog(
|
|
|
|
|
context: Get.overlayContext!,
|
2024-04-07 17:32:46 +08:00
|
|
|
|
barrierDismissible: barrierDismissible,
|
|
|
|
|
builder: builder ??
|
|
|
|
|
(context) {
|
|
|
|
|
return AlertDialog(
|
|
|
|
|
clipBehavior: Clip.hardEdge,
|
|
|
|
|
backgroundColor: AppTheme.nearlyWhite,
|
|
|
|
|
shape: RoundedRectangleBorder(
|
|
|
|
|
borderRadius: BorderRadius.circular(ScreenAdaper.sp(20)),
|
|
|
|
|
),
|
|
|
|
|
actionsPadding: EdgeInsets.zero,
|
|
|
|
|
titlePadding: EdgeInsets.zero,
|
|
|
|
|
contentPadding: contentPadding ??
|
|
|
|
|
EdgeInsets.symmetric(
|
2024-04-12 09:56:00 +08:00
|
|
|
|
vertical: ScreenAdaper.height(15),
|
|
|
|
|
horizontal: ScreenAdaper.width(25)),
|
2024-04-07 17:32:46 +08:00
|
|
|
|
title: title != null
|
|
|
|
|
? Container(
|
|
|
|
|
padding: EdgeInsets.symmetric(
|
2024-04-12 09:56:00 +08:00
|
|
|
|
vertical: ScreenAdaper.height(10),
|
2024-04-07 17:32:46 +08:00
|
|
|
|
),
|
|
|
|
|
decoration: const BoxDecoration(
|
|
|
|
|
border: Border(
|
|
|
|
|
bottom:
|
|
|
|
|
BorderSide(color: AppTheme.dividerColor))),
|
|
|
|
|
child: Row(
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
|
children: [
|
|
|
|
|
const Icon(
|
|
|
|
|
Icons.error_outline,
|
|
|
|
|
color: AppTheme.dangerColor,
|
|
|
|
|
),
|
|
|
|
|
SizedBox(
|
|
|
|
|
width: ScreenAdaper.width(10),
|
|
|
|
|
),
|
|
|
|
|
Text(
|
|
|
|
|
title,
|
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
|
style: TextStyle(
|
|
|
|
|
fontWeight: FontWeight.w500,
|
2024-04-12 09:56:00 +08:00
|
|
|
|
fontSize: ScreenAdaper.height(25),
|
2024-04-07 17:32:46 +08:00
|
|
|
|
color: AppTheme.black,
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
: null,
|
|
|
|
|
content: content ??
|
|
|
|
|
(contentText != null
|
|
|
|
|
? Container(
|
|
|
|
|
padding: EdgeInsets.symmetric(
|
|
|
|
|
vertical: ScreenAdaper.height(20),
|
|
|
|
|
),
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
border: Border(
|
|
|
|
|
bottom: BorderSide(
|
|
|
|
|
color: AppTheme.dividerColor,
|
|
|
|
|
width: ScreenAdaper.height(2)))),
|
|
|
|
|
child: Text(
|
|
|
|
|
// '${title}${title}${title}${title}${title}${title}${title}${title}${title}${title}${title}${title}${title}${title}${title}${title}${title}${title} ${title}${title}${title}${title}',
|
|
|
|
|
contentText,
|
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
|
style: TextStyle(
|
|
|
|
|
fontSize: ScreenAdaper.height(30),
|
|
|
|
|
fontWeight: FontWeight.w500),
|
|
|
|
|
))
|
|
|
|
|
: null),
|
|
|
|
|
actions: !showActions
|
|
|
|
|
? null
|
|
|
|
|
: [
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
|
if (showCancel)
|
|
|
|
|
Expanded(
|
|
|
|
|
child: InkWell(
|
|
|
|
|
onTap: () {
|
|
|
|
|
Navigator.of(context).pop();
|
|
|
|
|
confirmed = false;
|
2024-04-15 10:59:12 +08:00
|
|
|
|
if (onCancel != null) onCancel();
|
2024-04-07 17:32:46 +08:00
|
|
|
|
},
|
|
|
|
|
child: Container(
|
|
|
|
|
padding: EdgeInsets.symmetric(
|
|
|
|
|
vertical: ScreenAdaper.height(15)),
|
|
|
|
|
alignment: Alignment.center,
|
|
|
|
|
child: Text(
|
2024-04-15 10:59:12 +08:00
|
|
|
|
cancelText ?? '取消',
|
2024-04-07 17:32:46 +08:00
|
|
|
|
style: TextStyle(
|
|
|
|
|
color: Colors.black,
|
|
|
|
|
fontSize: ScreenAdaper.height(30)),
|
|
|
|
|
)),
|
|
|
|
|
)),
|
|
|
|
|
Expanded(
|
|
|
|
|
child: InkWell(
|
|
|
|
|
onTap: () {
|
|
|
|
|
Navigator.pop(context);
|
|
|
|
|
confirmed = true;
|
2024-04-15 10:59:12 +08:00
|
|
|
|
if (onConfirm != null) onConfirm();
|
2024-04-07 17:32:46 +08:00
|
|
|
|
},
|
|
|
|
|
child: Container(
|
|
|
|
|
padding: EdgeInsets.symmetric(
|
|
|
|
|
vertical: ScreenAdaper.height(15)),
|
|
|
|
|
alignment: Alignment.center,
|
|
|
|
|
child: Text(
|
|
|
|
|
confirmText ?? '确定',
|
|
|
|
|
style: TextStyle(
|
|
|
|
|
color: Colors.black,
|
|
|
|
|
fontSize: ScreenAdaper.height(30)),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
)),
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
},
|
2024-03-19 11:09:07 +08:00
|
|
|
|
);
|
|
|
|
|
return confirmed;
|
|
|
|
|
}
|
2024-03-25 14:16:00 +08:00
|
|
|
|
|
|
|
|
|
/// 底部选择器,支持3级
|
|
|
|
|
static Future<void> showBottomSheetPicker(
|
|
|
|
|
{title = '请选择',
|
|
|
|
|
required onChanged,
|
|
|
|
|
required firstLevel,
|
|
|
|
|
secondLevel,
|
|
|
|
|
thirdLevel,
|
|
|
|
|
itemHeight,
|
|
|
|
|
popupHeight}) async =>
|
|
|
|
|
showCupertinoModalPopup(
|
|
|
|
|
context: Get.overlayContext!,
|
|
|
|
|
builder: (BuildContext context) {
|
2024-04-01 08:41:52 +08:00
|
|
|
|
return SkBottomSheetPicker(
|
2024-03-25 14:16:00 +08:00
|
|
|
|
title: title,
|
|
|
|
|
onChanged: onChanged,
|
|
|
|
|
firstLevel: firstLevel,
|
|
|
|
|
secondLevel: secondLevel,
|
|
|
|
|
thirdLevel: thirdLevel,
|
|
|
|
|
itemHeight: itemHeight ?? 80.0,
|
|
|
|
|
popupHeight: popupHeight ?? 400);
|
|
|
|
|
},
|
|
|
|
|
);
|
2024-03-26 11:35:39 +08:00
|
|
|
|
|
2024-04-10 11:04:27 +08:00
|
|
|
|
static Future<T?> showGeneralDialog<T>(
|
2024-03-27 11:06:01 +08:00
|
|
|
|
{required Widget content,
|
|
|
|
|
double? width,
|
|
|
|
|
double? height,
|
|
|
|
|
Offset? offset}) {
|
2024-04-10 11:04:27 +08:00
|
|
|
|
return Get.generalDialog<T>(
|
2024-04-09 08:31:17 +08:00
|
|
|
|
barrierLabel: "generalDialog",
|
2024-03-26 11:35:39 +08:00
|
|
|
|
barrierDismissible: true,
|
|
|
|
|
transitionDuration: const Duration(milliseconds: 400),
|
|
|
|
|
pageBuilder: (_, __, ___) {
|
2024-04-10 11:04:27 +08:00
|
|
|
|
return SafeArea(
|
|
|
|
|
child: ScreenAdaper.isTablet()
|
|
|
|
|
? Center(
|
|
|
|
|
child: ClipRRect(
|
|
|
|
|
borderRadius:
|
|
|
|
|
BorderRadius.circular(ScreenAdaper.sp(30)),
|
|
|
|
|
child: Material(
|
|
|
|
|
child: SizedBox(
|
|
|
|
|
height:
|
|
|
|
|
height ?? Get.height - ScreenAdaper.height(150),
|
|
|
|
|
width: width ?? Get.width - ScreenAdaper.width(150),
|
|
|
|
|
child: content,
|
|
|
|
|
),
|
|
|
|
|
)))
|
|
|
|
|
: Container(
|
|
|
|
|
margin: EdgeInsets.only(top: Get.height / 10),
|
|
|
|
|
child: ClipRRect(
|
|
|
|
|
borderRadius: BorderRadius.only(
|
|
|
|
|
topLeft: Radius.circular(ScreenAdaper.sp(30)),
|
|
|
|
|
topRight: Radius.circular(ScreenAdaper.sp(30))),
|
|
|
|
|
child: Material(
|
|
|
|
|
child: content,
|
|
|
|
|
),
|
|
|
|
|
)));
|
2024-03-26 11:35:39 +08:00
|
|
|
|
},
|
|
|
|
|
transitionBuilder: (_, anim, __, child) {
|
|
|
|
|
Tween<Offset> tween;
|
2024-03-27 11:06:01 +08:00
|
|
|
|
tween = Tween(begin: offset ?? const Offset(0, 1), end: Offset.zero);
|
2024-03-26 11:35:39 +08:00
|
|
|
|
return SlideTransition(
|
|
|
|
|
position: tween.animate(
|
|
|
|
|
CurvedAnimation(parent: anim, curve: Curves.easeInOut),
|
|
|
|
|
),
|
|
|
|
|
child: child,
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
2024-03-19 11:09:07 +08:00
|
|
|
|
}
|