starwork_flutter/lib/views/messages/messages_view.dart

426 lines
13 KiB
Dart
Raw Permalink Normal View History

import 'package:flutter/cupertino.dart';
2025-08-27 18:20:37 +08:00
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
2025-08-27 18:20:37 +08:00
import 'package:get/get.dart';
import 'package:starwork_flutter/base/app_permission.dart';
2025-08-27 18:20:37 +08:00
import 'messages_controller.dart';
import 'messages_model.dart';
2025-08-27 18:20:37 +08:00
class MessagesView extends GetView<MessagesController> {
const MessagesView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFF6F7FB),
body: SafeArea(
child: Container(
width: 1.sw,
padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 4.h),
child: Column(
children: [
// 固定的上半部分
_buildPageHead(context),
_buildSystemNotificationPermissionRow(),
Obx(
() => Visibility(
visible: controller
.homeController.isOpenNotificationPermission.value,
child: SizedBox(
height: 10.h,
),
),
),
// 消息列表
Expanded(
child: _buildRefreshableMessageList(),
),
],
),
),
),
);
}
_buildPageHead(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// 左侧标题区域
Expanded(
child: GestureDetector(
onTap: () {
controller.mainController.scaffoldKey.currentState?.openDrawer();
},
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: Text(
'19104656的互12312联',
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.w600,
color: Colors.black87,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
Icon(
Icons.arrow_right_rounded,
size: 22.sp,
),
],
),
),
),
// 右侧功能按钮区域
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.min,
children: [
// 清除未读按钮
Flexible(
child: GestureDetector(
onTap: () {
// 处理清除未读点击事件
controller.clearAllUnread();
print('清除未读被点击');
},
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 6.w, // 减小内边距
vertical: 3.h,
),
decoration: BoxDecoration(
color: const Color(0xFFF0F0F0),
borderRadius: BorderRadius.circular(12.r),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: Text(
'清除未读',
style: TextStyle(
fontSize: 12.sp, // 减小字体
color: Colors.black54,
fontWeight: FontWeight.w400,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
],
),
),
),
),
// 分隔线
Container(
height: 16.h, // 减小高度
width: 1.w,
color: Colors.grey.withOpacity(0.3),
),
// 通知设置按钮
Flexible(
child: GestureDetector(
onTap: () {
// 处理通知设置点击事件
print('通知设置被点击');
},
child: Text(
'通知设置',
style: TextStyle(
fontSize: 14.sp, // 减小字体
color: Colors.black,
fontWeight: FontWeight.w400,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
),
],
),
),
],
);
}
_buildSystemNotificationPermissionRow() {
return Obx(
() => Visibility(
visible: !controller.homeController.isOpenNotificationPermission.value,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 4.h),
decoration: BoxDecoration(
color: const Color(0xFFFEF2E5),
borderRadius: BorderRadius.all(
Radius.circular(8.r),
),
),
margin: EdgeInsets.symmetric(vertical: 8.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'系统通知未开启,报警消息无法通知'.tr,
style: TextStyle(
color: const Color(0xFFEE9846),
fontSize: 12.sp,
),
),
const Spacer(),
GestureDetector(
onTap: () async {
controller.homeController.isOpenNotificationPermission.value =
await AppPermission.requestNotificationPermission();
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 6.w, vertical: 4.h),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(4.r),
),
),
child: Text(
'去开启'.tr,
style: TextStyle(
color: const Color(0xFFEE9846),
fontSize: 12.sp,
),
),
),
),
SizedBox(
width: 14.w,
),
GestureDetector(
onTap: () {
controller.homeController.isOpenNotificationPermission.value =
true;
},
child: Icon(
Icons.cancel,
color: const Color(0xFFEE9846),
size: 18.sp,
),
)
],
),
),
2025-08-27 18:20:37 +08:00
),
);
}
_buildRefreshableMessageList() {
return RefreshIndicator(
onRefresh: _onRefresh,
// 基础样式配置
color: const Color(0xFF4A90E2),
// 刷新指示器颜色
backgroundColor: Colors.white,
// 背景颜色
// 控制下拉触发距离的关键属性
displacement: 60.0,
// 刷新指示器距离顶部的距离默认40.0
edgeOffset: 0.0,
// 边缘偏移量默认0.0
// 控制下拉幅度的关键属性
triggerMode: RefreshIndicatorTriggerMode.onEdge,
// 触发模式
// RefreshIndicatorTriggerMode.onEdge: 在边缘触发(默认)
// RefreshIndicatorTriggerMode.anywhere: 在任何位置都可以触发
// 描边宽度
strokeWidth: 2.5,
// 刷新指示器的描边宽度默认2.0
// 语义标签(用于无障碍功能)
semanticsLabel: '下拉刷新消息列表',
semanticsValue: '刷新中...',
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(
// 控制滚动物理特性
parent: BouncingScrollPhysics(), // 添加弹性滚动效果
),
child: Column(
children: [
_buildMessageList(),
SizedBox(height: 16.h),
_buildMessageTip(),
],
2025-08-27 18:20:37 +08:00
),
),
);
}
Future<void> _onRefresh() async {
// 调用controller的刷新方法
await controller.refreshMessages();
}
_buildMessageList() {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8.r),
),
child: Obx(
() => Column(
children: [
// 动态生成消息列表项
...controller.messageList.asMap().entries.map((entry) {
int index = entry.key;
MessageItem message = entry.value;
return Column(
children: [
_buildMessageItem(
message: message,
onTap: () => _onMessageTap(index, message),
),
// 如果不是最后一项,显示分隔线
if (index < controller.messageList.length - 1)
_buildDivider(),
],
);
}).toList(),
],
),
),
);
}
_buildMessageTip() {
return Container(
padding: EdgeInsets.symmetric(vertical: 10.h),
child: Text(
'只展示最近7天的消息',
style: TextStyle(
fontSize: 12.sp,
color: Colors.grey[500],
fontWeight: FontWeight.w400,
),
),
);
}
_buildMessageItem({
required MessageItem message,
VoidCallback? onTap,
}) {
return GestureDetector(
onTap: onTap ??
() {
// 默认点击事件
print('${message.title} 被点击');
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
child: Row(
children: [
// 左侧图标
Stack(
children: [
Container(
width: 40.w,
height: 40.w,
decoration: BoxDecoration(
color: message.iconBgColor,
borderRadius: BorderRadius.circular(8.r),
),
child: Icon(
message.icon,
color: message.iconColor,
size: 20.sp,
),
),
if (message.hasRedDot)
Positioned(
top: 0,
right: 0,
child: Container(
width: 8.w,
height: 8.w,
decoration: const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
),
),
],
),
SizedBox(width: 12.w),
// 中间内容
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
message.title,
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: Colors.black87,
),
),
SizedBox(height: 4.h),
Text(
message.subtitle,
style: TextStyle(
fontSize: 14.sp,
color: Colors.grey[600],
fontWeight: FontWeight.w400,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
),
// 右侧时间
if (message.time.isNotEmpty)
Text(
message.time,
style: TextStyle(
fontSize: 12.sp,
color: Colors.grey[400],
fontWeight: FontWeight.w400,
),
),
],
),
),
);
}
// 处理消息项点击事件
void _onMessageTap(int index, MessageItem message) {
print('${message.title} 被点击,索引: $index');
// 这里可以添加具体的业务逻辑,比如跳转到详情页面
// 如果有未读标记,可以标记为已读
if (message.hasRedDot) {
// 可以在这里调用controller的方法标记为已读
}
}
_buildDivider() {
return Container(
margin: EdgeInsets.symmetric(horizontal: 16.w),
height: 1.h,
color: Colors.grey[200],
);
}
2025-08-27 18:20:37 +08:00
}