diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 533f5bb..7665c8b 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -11,6 +11,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{
builder: (_, child) {
return GetMaterialApp(
theme: ThemeData(
- scaffoldBackgroundColor: Colors.white,
- brightness: Brightness.light,
- textSelectionTheme: TextSelectionThemeData(
- cursorColor: Colors.blue.shade200,
- selectionColor: Colors.blue.shade100,
- selectionHandleColor: Colors.blue.shade300,
- ),
- dialogBackgroundColor: Colors.white,
- ),
+ scaffoldBackgroundColor: Colors.white,
+ brightness: Brightness.light,
+ textSelectionTheme: TextSelectionThemeData(
+ cursorColor: Colors.blue.shade200,
+ selectionColor: Colors.blue.shade100,
+ selectionHandleColor: Colors.blue.shade300,
+ ),
+ dialogBackgroundColor: Colors.white,
+ appBarTheme: AppBarTheme(
+ backgroundColor: Colors.white,
+ )),
// 必须配置以下三个本地化代理
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate, // 提供Material组件本地化字符串
diff --git a/lib/base/app_permission.dart b/lib/base/app_permission.dart
index 2d02f33..fd117c4 100644
--- a/lib/base/app_permission.dart
+++ b/lib/base/app_permission.dart
@@ -46,4 +46,132 @@ class AppPermission {
return false;
}
+
+ // 请求蓝牙权限(Android 12及以上需要)
+ static Future requestBluetoothPermissions() async {
+ try {
+ // Android 12及以上需要的蓝牙权限
+ List bluetoothPermissions = [
+ Permission.bluetoothScan,
+ Permission.bluetoothConnect,
+ Permission.bluetoothAdvertise,
+ ];
+
+ // Android 12以下需要的位置权限
+ List locationPermissions = [
+ Permission.location,
+ Permission.locationWhenInUse,
+ ];
+
+ bool bluetoothGranted = true;
+ bool locationGranted = true;
+
+ // 检查并请求蓝牙权限(Android 12+)
+ Map bluetoothStatuses = await bluetoothPermissions.request();
+ for (var status in bluetoothStatuses.values) {
+ if (status != PermissionStatus.granted) {
+ bluetoothGranted = false;
+ break;
+ }
+ }
+
+ // 检查并请求位置权限(Android 12以下或蓝牙扫描需要)
+ Map locationStatuses = await locationPermissions.request();
+ for (var status in locationStatuses.values) {
+ if (status != PermissionStatus.granted) {
+ locationGranted = false;
+ break;
+ }
+ }
+
+ bool hasPermission = bluetoothGranted && locationGranted;
+
+ if (hasPermission) {
+ print("蓝牙权限已授予");
+ } else {
+ print("蓝牙权限被拒绝");
+ }
+
+ return hasPermission;
+
+ } catch (e) {
+ print("请求蓝牙权限失败: $e");
+ return false;
+ }
+ }
+
+ // 检查蓝牙扫描权限
+ static Future checkBluetoothScanPermission() async {
+ try {
+ var status = await Permission.bluetoothScan.status;
+ return status == PermissionStatus.granted;
+ } catch (e) {
+ // 如果权限不存在(Android 12以下),检查位置权限
+ return await checkLocationPermission();
+ }
+ }
+
+ // 检查蓝牙连接权限
+ static Future checkBluetoothConnectPermission() async {
+ try {
+ var status = await Permission.bluetoothConnect.status;
+ return status == PermissionStatus.granted;
+ } catch (e) {
+ // 如果权限不存在(Android 12以下),默认返回true
+ print("蓝牙连接权限检查失败,可能是Android 12以下版本: $e");
+ return true;
+ }
+ }
+
+ // 检查蓝牙广播权限
+ static Future checkBluetoothAdvertisePermission() async {
+ try {
+ var status = await Permission.bluetoothAdvertise.status;
+ return status == PermissionStatus.granted;
+ } catch (e) {
+ // 如果权限不存在(Android 12以下),默认返回true
+ print("蓝牙广播权限检查失败,可能是Android 12以下版本: $e");
+ return true;
+ }
+ }
+
+ // 检查位置权限(Android 12以下蓝牙扫描需要)
+ static Future checkLocationPermission() async {
+ var status = await Permission.location.status;
+ return status == PermissionStatus.granted;
+ }
+
+ // 请求位置权限
+ static Future requestLocationPermission() async {
+ try {
+ final PermissionStatus status = await Permission.location.request();
+
+ if (status == PermissionStatus.granted) {
+ print("位置权限已授予");
+ return true;
+ } else if (status == PermissionStatus.denied) {
+ print("位置权限被拒绝");
+ return false;
+ } else if (status.isPermanentlyDenied) {
+ print("位置权限被永久拒绝,跳转到设置页面");
+ openAppSettings();
+ return false;
+ }
+
+ return false;
+ } catch (e) {
+ print("请求位置权限失败: $e");
+ return false;
+ }
+ }
+
+ // 检查所有蓝牙相关权限
+ static Future checkAllBluetoothPermissions() async {
+ bool scanPermission = await checkBluetoothScanPermission();
+ bool connectPermission = await checkBluetoothConnectPermission();
+ bool advertisePermission = await checkBluetoothAdvertisePermission();
+ bool locationPermission = await checkLocationPermission();
+
+ return scanPermission && connectPermission && advertisePermission && locationPermission;
+ }
}
diff --git a/lib/base/base_controller.dart b/lib/base/base_controller.dart
index 6130de9..6fa1bba 100644
--- a/lib/base/base_controller.dart
+++ b/lib/base/base_controller.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
+import 'package:starwork_flutter/common/widgets/custom_dialog_widget.dart';
class BaseController extends GetxController {
void showToast(String message) {
@@ -24,6 +25,24 @@ class BaseController extends GetxController {
EasyLoading.showError(message.tr);
}
+ void showCustomDialog({
+ required String title,
+ required Widget content,
+ required VoidCallback onConfirm,
+ String? confirmText
+ }) {
+ Get.dialog(
+ CustomDialogWidget(
+ title: title,
+ content: content,
+ onConfirm: onConfirm,
+ confirmText: confirmText,
+ ),
+ barrierDismissible: false, // 点击遮罩是否关闭
+ useSafeArea: true, // 推荐保持默认
+ );
+ }
+
@override
void onClose() {
if (EasyLoading.isShow) {
diff --git a/lib/common/widgets/custom_dialog_widget.dart b/lib/common/widgets/custom_dialog_widget.dart
new file mode 100644
index 0000000..5bb3d25
--- /dev/null
+++ b/lib/common/widgets/custom_dialog_widget.dart
@@ -0,0 +1,110 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
+
+class CustomDialogWidget extends StatefulWidget {
+ CustomDialogWidget({
+ super.key,
+ required this.title,
+ required this.content,
+ required this.onConfirm,
+ String? confirmText,
+ }) : confirmText = confirmText ?? '确认'.tr;
+
+ final String title;
+ final Widget content;
+ final VoidCallback onConfirm;
+ final String confirmText;
+
+ @override
+ State createState() => _CustomDialogWidgetState();
+}
+
+class _CustomDialogWidgetState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Dialog(
+ backgroundColor: Colors.white,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(14.r), // 圆角
+ ),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ SizedBox(height: 18.h),
+ Text(
+ widget.title,
+ style: TextStyle(
+ fontSize: 18.sp,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 10.h),
+ widget.content,
+ SizedBox(height: 10.h),
+ Container(
+ decoration: const BoxDecoration(
+ border: Border(
+ top: BorderSide(
+ color: Colors.grey, // 右侧边框颜色
+ width: 0.5, // 右侧边框宽度
+ ),
+ ),
+ ),
+ child: Row(
+ children: [
+ Expanded(
+ // 左侧文本占一半
+ child: GestureDetector(
+ onTap: () {
+ Get.back();
+ },
+ child: Container(
+ alignment: Alignment.center,
+ height: 42.h,
+ decoration: const BoxDecoration(
+ border: Border(
+ right: BorderSide(
+ color: Colors.grey, // 右侧边框颜色
+ width: 0.5, // 右侧边框宽度
+ ),
+ ),
+ ),
+ child: Text(
+ '取消'.tr,
+ textAlign: TextAlign.center,
+ style: TextStyle(fontSize: 14.sp, color: Colors.grey),
+ ),
+ ),
+ ),
+ ),
+ Expanded(
+ // 右侧文本占一半
+ child: GestureDetector(
+ onTap: () {
+ Get.back();
+ widget.onConfirm();
+ },
+ child: Container(
+ alignment: Alignment.center,
+ height: 42.h,
+ child: Text(
+ widget.confirmText,
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 14.sp,
+ color: Colors.blue,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ )
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/flavors.dart b/lib/flavors.dart
index e64b804..99d932f 100644
--- a/lib/flavors.dart
+++ b/lib/flavors.dart
@@ -32,7 +32,7 @@ class F {
static String get apiHost {
switch (appFlavor) {
case Flavor.skyDev:
- return 'http://10.0.2.2/api';
+ return 'http://192.168.1.136/api';
case Flavor.skyPre:
return 'https://loacl.work.star-lock.cn/api';
case Flavor.skyRelease:
diff --git a/lib/routes/app_pages.dart b/lib/routes/app_pages.dart
index d05c11f..52444d6 100644
--- a/lib/routes/app_pages.dart
+++ b/lib/routes/app_pages.dart
@@ -1,5 +1,7 @@
import 'package:get/get.dart';
import 'package:starwork_flutter/routes/app_routes.dart';
+import 'package:starwork_flutter/views/device/searchDevice/search_device_binding.dart';
+import 'package:starwork_flutter/views/device/searchDevice/search_device_view.dart';
import 'package:starwork_flutter/views/home/home_binding.dart';
import 'package:starwork_flutter/views/home/home_view.dart';
import 'package:starwork_flutter/views/login/forgotPassword/forgot_password_binding.dart';
@@ -60,5 +62,10 @@ class AppPages {
page: () => const SetNewPasswordView(),
binding: SetNewPasswordBinding(),
),
+ GetPage(
+ name: AppRoutes.searchDevice,
+ page: () => const SearchDeviceView(),
+ binding: SearchDeviceBinding(),
+ ),
];
}
diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart
index c50736b..1994e8b 100644
--- a/lib/routes/app_routes.dart
+++ b/lib/routes/app_routes.dart
@@ -8,4 +8,5 @@ class AppRoutes{
static const String inputVerificationCode = '/inputVerificationCode';
static const String forgotPassword = '/forgotPassword';
static const String setNewPassword = '/setNewPassword';
+ static const String searchDevice = '/searchDevice';
}
\ No newline at end of file
diff --git a/lib/views/device/searchDevice/search_device_binding.dart b/lib/views/device/searchDevice/search_device_binding.dart
new file mode 100644
index 0000000..909ffda
--- /dev/null
+++ b/lib/views/device/searchDevice/search_device_binding.dart
@@ -0,0 +1,9 @@
+import 'package:get/get.dart';
+import 'package:starwork_flutter/views/device/searchDevice/search_device_controller.dart';
+
+class SearchDeviceBinding extends Bindings {
+ @override
+ void dependencies() {
+ Get.lazyPut(() => SearchDeviceController());
+ }
+}
diff --git a/lib/views/device/searchDevice/search_device_controller.dart b/lib/views/device/searchDevice/search_device_controller.dart
new file mode 100644
index 0000000..16d9a66
--- /dev/null
+++ b/lib/views/device/searchDevice/search_device_controller.dart
@@ -0,0 +1,22 @@
+import 'dart:ui';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_blue_plus/flutter_blue_plus.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
+import 'package:permission_handler/permission_handler.dart';
+import 'package:starwork_flutter/base/app_permission.dart';
+import 'package:starwork_flutter/base/base_controller.dart';
+
+class SearchDeviceController extends BaseController {
+ // 搜索状态管理
+ final RxBool _isSearching = false.obs;
+
+ // Getter
+ bool get isSearching => _isSearching.value;
+
+ @override
+ void onInit() async {
+ super.onInit();
+ }
+}
diff --git a/lib/views/device/searchDevice/search_device_view.dart b/lib/views/device/searchDevice/search_device_view.dart
new file mode 100644
index 0000000..8ec92f2
--- /dev/null
+++ b/lib/views/device/searchDevice/search_device_view.dart
@@ -0,0 +1,42 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
+import 'package:starwork_flutter/views/device/searchDevice/search_device_controller.dart';
+import 'package:starwork_flutter/views/device/searchDevice/widget/search_device_rotating_icon_widget.dart';
+
+class SearchDeviceView extends GetView {
+ const SearchDeviceView({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Row(
+ children: [
+ Obx(() => Text(
+ controller.isSearching ? '搜索设备中'.tr : '搜索设备'.tr,
+ )),
+ SizedBox(
+ width: 8.w,
+ ),
+ Obx(
+ () => SearchDeviceRotatingIconWidget(
+ isRotating: controller.isSearching,
+ radius: 10.w,
+ rotationDuration: 1500,
+ ),
+ ),
+ ],
+ ),
+ ),
+ body: Container(
+ // TODO: 添加设备搜索结果列表
+ child: Center(
+ child: Text('设备搜索页面'),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/views/device/searchDevice/widget/search_device_rotating_icon_widget.dart b/lib/views/device/searchDevice/widget/search_device_rotating_icon_widget.dart
new file mode 100644
index 0000000..07140f6
--- /dev/null
+++ b/lib/views/device/searchDevice/widget/search_device_rotating_icon_widget.dart
@@ -0,0 +1,100 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+
+class SearchDeviceRotatingIconWidget extends StatefulWidget {
+ /// 是否正在旋转
+ final bool isRotating;
+ /// 旋转速度(毫秒)
+ final int rotationDuration;
+ /// 图标颜色
+ final Color? color;
+ /// 图标半径
+ final double? radius;
+
+ const SearchDeviceRotatingIconWidget({
+ super.key,
+ required this.isRotating,
+ this.rotationDuration = 1000,
+ this.color = Colors.grey,
+ this.radius,
+ });
+
+ @override
+ _SearchDeviceRotatingIconWidgetState createState() => _SearchDeviceRotatingIconWidgetState();
+}
+
+class _SearchDeviceRotatingIconWidgetState extends State
+ with SingleTickerProviderStateMixin {
+ late AnimationController _animationController;
+
+ @override
+ void initState() {
+ super.initState();
+ _animationController = AnimationController(
+ duration: Duration(milliseconds: widget.rotationDuration),
+ vsync: this,
+ );
+
+ // 根据初始状态决定是否开始动画
+ if (widget.isRotating) {
+ _animationController.repeat();
+ }
+ }
+
+ @override
+ void didUpdateWidget(SearchDeviceRotatingIconWidget oldWidget) {
+ super.didUpdateWidget(oldWidget);
+
+ // 当isRotating状态发生变化时,控制动画的开始和停止
+ if (widget.isRotating != oldWidget.isRotating) {
+ if (widget.isRotating) {
+ _startRotation();
+ } else {
+ _stopRotation();
+ }
+ }
+
+ // 当旋转速度发生变化时,更新动画时长
+ if (widget.rotationDuration != oldWidget.rotationDuration) {
+ _animationController.duration = Duration(milliseconds: widget.rotationDuration);
+ }
+ }
+
+ @override
+ void dispose() {
+ _animationController.dispose();
+ super.dispose();
+ }
+
+ /// 开始旋转动画
+ void _startRotation() {
+ if (!_animationController.isAnimating) {
+ _animationController.repeat();
+ }
+ }
+
+ /// 停止旋转动画
+ void _stopRotation() {
+ if (_animationController.isAnimating) {
+ _animationController.stop();
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return AnimatedBuilder(
+ animation: _animationController,
+ builder: (context, child) {
+ return Transform.rotate(
+ angle: _animationController.value * 2 * 3.14159,
+ child: CupertinoActivityIndicator(
+ radius: widget.radius ?? 10.w,
+ color: widget.color,
+ ),
+ );
+ },
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/views/home/home_view.dart b/lib/views/home/home_view.dart
index 5b6ec5d..3432a03 100644
--- a/lib/views/home/home_view.dart
+++ b/lib/views/home/home_view.dart
@@ -4,6 +4,7 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:starwork_flutter/base/app_permission.dart';
+import 'package:starwork_flutter/routes/app_routes.dart';
import 'package:super_tooltip/super_tooltip.dart';
import 'package:starwork_flutter/views/home/widget/home_attendance_chart_area_widget.dart';
import 'package:starwork_flutter/views/home/widget/home_carousel_area_widget.dart';
@@ -175,10 +176,15 @@ class HomeView extends GetView {
SizedBox(
width: 14.w,
),
- Icon(
- Icons.cancel,
- color: const Color(0xFFEE9846),
- size: 18.sp,
+ GestureDetector(
+ onTap: () {
+ controller.isOpenNotificationPermission.value = true;
+ },
+ child: Icon(
+ Icons.cancel,
+ color: const Color(0xFFEE9846),
+ size: 18.sp,
+ ),
)
],
),
@@ -263,12 +269,12 @@ class HomeView extends GetView {
{
'title': '搜索设备',
'icon': Icons.sensors_rounded,
- 'onTap': () => _handleMenuTap('添加设备'),
+ 'onTap': () => _handleMenuTap(0),
},
{
'title': '加入团队',
'icon': Icons.group_add,
- 'onTap': () => _handleMenuTap('创建群组'),
+ 'onTap': () => _handleMenuTap(1),
},
];
@@ -329,7 +335,9 @@ class HomeView extends GetView {
size: 18.sp,
color: Colors.black87,
),
- SizedBox(width: 8.w,),
+ SizedBox(
+ width: 8.w,
+ ),
Flexible(
child: Text(
title,
@@ -348,12 +356,13 @@ class HomeView extends GetView {
}
/// 处理菜单点击事件
- void _handleMenuTap(String menuTitle) {
- Get.snackbar(
- '提示',
- '点击了:$menuTitle',
- snackPosition: SnackPosition.TOP,
- duration: const Duration(seconds: 2),
- );
+ void _handleMenuTap(int menuIndex) {
+ switch (menuIndex) {
+ case 0:
+ Get.toNamed(AppRoutes.searchDevice);
+ break;
+ case 1:
+ break;
+ }
}
}
diff --git a/lib/views/login/login_controller.dart b/lib/views/login/login_controller.dart
index 724a1cb..5d1de43 100644
--- a/lib/views/login/login_controller.dart
+++ b/lib/views/login/login_controller.dart
@@ -72,127 +72,44 @@ class LoginController extends BaseController {
required String content,
required VoidCallback onConfirm,
}) {
- Get.dialog(
- Dialog(
- backgroundColor: Colors.white,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(14.r), // 圆角
- ),
- child: Column(
- mainAxisSize: MainAxisSize.min,
+ showCustomDialog(
+ title: title,
+ content: RichText(
+ text: TextSpan(
children: [
- Padding(
- padding: EdgeInsets.only(top: 22.h),
- child: Text(
- title,
- style: TextStyle(
- fontSize: 18.sp,
- fontWeight: FontWeight.bold,
- ),
+ TextSpan(
+ text: '请你阅读并同意'.tr,
+ style: TextStyle(
+ fontSize: 12.sp,
+ color: Colors.grey,
),
),
- Padding(
- padding: EdgeInsets.all(22.w),
- child: RichText(
- text: TextSpan(
- children: [
- TextSpan(
- text: '请你阅读并同意'.tr,
- style: TextStyle(
- fontSize: 12.sp,
- color: Colors.grey,
- ),
- ),
- TextSpan(
- text: '《用户协议》'.tr,
- style: TextStyle(
- fontSize: 12.sp,
- color: Colors.blue,
- ),
- ),
- TextSpan(
- text: '和'.tr,
- style: TextStyle(
- fontSize: 12.sp,
- color: Colors.grey,
- ),
- ),
- TextSpan(
- text: '《隐私政策》'.tr,
- style: TextStyle(
- fontSize: 12.sp,
- color: Colors.blue,
- ),
- ),
- ],
- ),
+ TextSpan(
+ text: '《用户协议》'.tr,
+ style: TextStyle(
+ fontSize: 12.sp,
+ color: Colors.blue,
),
),
- SizedBox(height: 20.h),
- Container(
- decoration: const BoxDecoration(
- border: Border(
- top: BorderSide(
- color: Colors.grey, // 右侧边框颜色
- width: 0.5, // 右侧边框宽度
- ),
- ),
+ TextSpan(
+ text: '和'.tr,
+ style: TextStyle(
+ fontSize: 12.sp,
+ color: Colors.grey,
),
- child: Row(
- children: [
- Expanded(
- // 左侧文本占一半
- child: GestureDetector(
- onTap: () {
- Get.back();
- },
- child: Container(
- alignment: Alignment.center,
- height: 42.h,
- decoration: const BoxDecoration(
- border: Border(
- right: BorderSide(
- color: Colors.grey, // 右侧边框颜色
- width: 0.5, // 右侧边框宽度
- ),
- ),
- ),
- child: Text(
- '取消'.tr,
- textAlign: TextAlign.center,
- style: TextStyle(fontSize: 14.sp, color: Colors.grey),
- ),
- ),
- ),
- ),
- Expanded(
- // 右侧文本占一半
- child: GestureDetector(
- onTap: () {
- Get.back();
- onConfirm();
- },
- child: Container(
- alignment: Alignment.center,
- height: 42.h,
- child: Text(
- '同意并继续'.tr,
- textAlign: TextAlign.center,
- style: TextStyle(
- fontSize: 14.sp,
- color: Colors.blue,
- fontWeight: FontWeight.w600,
- ),
- ),
- ),
- ),
- ),
- ],
+ ),
+ TextSpan(
+ text: '《隐私政策》'.tr,
+ style: TextStyle(
+ fontSize: 12.sp,
+ color: Colors.blue,
),
- )
+ ),
],
),
),
+ onConfirm: onConfirm,
+ confirmText: '同意并继续'.tr,
);
}
}
diff --git a/lib/views/messages/messages_view.dart b/lib/views/messages/messages_view.dart
index 9e5989a..b352895 100644
--- a/lib/views/messages/messages_view.dart
+++ b/lib/views/messages/messages_view.dart
@@ -1,5 +1,6 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:starwork_flutter/base/app_permission.dart';
@@ -201,10 +202,16 @@ class MessagesView extends GetView {
SizedBox(
width: 14.w,
),
- Icon(
- Icons.cancel,
- color: const Color(0xFFEE9846),
- size: 18.sp,
+ GestureDetector(
+ onTap: () {
+ controller.homeController.isOpenNotificationPermission.value =
+ true;
+ },
+ child: Icon(
+ Icons.cancel,
+ color: const Color(0xFFEE9846),
+ size: 18.sp,
+ ),
)
],
),
@@ -217,25 +224,31 @@ class MessagesView extends GetView {
return RefreshIndicator(
onRefresh: _onRefresh,
// 基础样式配置
- color: const Color(0xFF4A90E2), // 刷新指示器颜色
- backgroundColor: Colors.white, // 背景颜色
-
+ color: const Color(0xFF4A90E2),
+ // 刷新指示器颜色
+ backgroundColor: Colors.white,
+ // 背景颜色
+
// 控制下拉触发距离的关键属性
- displacement: 60.0, // 刷新指示器距离顶部的距离(默认40.0)
- edgeOffset: 0.0, // 边缘偏移量(默认0.0)
-
+ displacement: 60.0,
+ // 刷新指示器距离顶部的距离(默认40.0)
+ edgeOffset: 0.0,
+ // 边缘偏移量(默认0.0)
+
// 控制下拉幅度的关键属性
- triggerMode: RefreshIndicatorTriggerMode.onEdge, // 触发模式
+ triggerMode: RefreshIndicatorTriggerMode.onEdge,
+ // 触发模式
// RefreshIndicatorTriggerMode.onEdge: 在边缘触发(默认)
// RefreshIndicatorTriggerMode.anywhere: 在任何位置都可以触发
-
+
// 描边宽度
- strokeWidth: 2.5, // 刷新指示器的描边宽度(默认2.0)
-
+ strokeWidth: 2.5,
+ // 刷新指示器的描边宽度(默认2.0)
+
// 语义标签(用于无障碍功能)
semanticsLabel: '下拉刷新消息列表',
semanticsValue: '刷新中...',
-
+
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(
// 控制滚动物理特性