2025-07-03 09:45:15 +08:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:qhd_prevention/customWidget/search_bar_widget.dart';
|
2025-07-07 16:49:05 +08:00
|
|
|
import 'package:qhd_prevention/pages/notif/notif_detail_page.dart';
|
|
|
|
import 'package:qhd_prevention/tools/tools.dart';
|
2025-07-03 09:45:15 +08:00
|
|
|
|
|
|
|
class NotifPage extends StatefulWidget {
|
|
|
|
const NotifPage({Key? key}) : super(key: key);
|
|
|
|
|
|
|
|
@override
|
|
|
|
_NotifPageState createState() => _NotifPageState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _NotifPageState extends State<NotifPage> with SingleTickerProviderStateMixin {
|
|
|
|
late TabController _tabController;
|
|
|
|
int _selectedTab = 0;
|
|
|
|
|
|
|
|
// 模拟数据
|
|
|
|
final List<Map<String, dynamic>> _notifications = List.generate(10, (i) {
|
|
|
|
bool read = i % 3 == 0;
|
|
|
|
return {
|
|
|
|
'title': '测试数据标题标题 ${i + 1}',
|
|
|
|
'time': '2025-06-${10 + i} 12:3${i}',
|
|
|
|
'read': read,
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
|
|
|
_tabController = TabController(length: 2, vsync: this);
|
|
|
|
_tabController.addListener(() {
|
|
|
|
if (!_tabController.indexIsChanging) {
|
|
|
|
setState(() => _selectedTab = _tabController.index);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void dispose() {
|
|
|
|
_tabController.dispose();
|
|
|
|
super.dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
final TextEditingController searchController = TextEditingController();
|
|
|
|
|
|
|
|
return GestureDetector(
|
|
|
|
onTap: () {
|
|
|
|
FocusScope.of(context).unfocus(); // 收起键盘
|
|
|
|
},
|
|
|
|
behavior: HitTestBehavior.opaque,
|
|
|
|
child: Scaffold(
|
|
|
|
body: SafeArea(
|
|
|
|
child:Column(
|
|
|
|
children: [
|
|
|
|
// Tab bar
|
|
|
|
TabBar(
|
|
|
|
controller: _tabController,
|
|
|
|
labelStyle: TextStyle(fontSize: 16),
|
|
|
|
indicator: UnderlineTabIndicator(
|
|
|
|
borderSide: BorderSide(width: 3.0, color: Colors.blue),
|
|
|
|
insets: EdgeInsets.symmetric(horizontal: 100.0),
|
|
|
|
),
|
|
|
|
labelColor: Colors.blue,
|
|
|
|
unselectedLabelColor: Colors.grey,
|
|
|
|
tabs: const [
|
|
|
|
Tab(text: '政府公告'),
|
|
|
|
Tab(text: '企业公告'),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
|
|
|
|
// Search bar
|
|
|
|
Padding(
|
|
|
|
padding: const EdgeInsets.all(10),
|
|
|
|
child: SearchBarWidget(
|
|
|
|
controller: searchController,
|
|
|
|
onSearch: (keyword) {
|
|
|
|
print("用户输入的是: $keyword");
|
|
|
|
// TODO: 执行搜索
|
|
|
|
},
|
|
|
|
)
|
|
|
|
),
|
|
|
|
|
|
|
|
// List
|
|
|
|
Expanded(
|
|
|
|
child: ListView.separated(
|
|
|
|
itemCount: _notifications.length,
|
|
|
|
separatorBuilder: (_, __) => const Divider(height: 1),
|
|
|
|
itemBuilder: (context, index) {
|
|
|
|
final item = _notifications[index];
|
|
|
|
return _itemCell(item);
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget _itemCell(final item) {
|
|
|
|
return ListTile(
|
2025-07-07 16:49:05 +08:00
|
|
|
onTap: () {
|
|
|
|
pushPage(NotifDetailPage(), context);
|
|
|
|
},
|
2025-07-03 09:45:15 +08:00
|
|
|
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
|
|
|
title: Padding(
|
|
|
|
padding: const EdgeInsets.only(bottom: 20), // 减小底部间距
|
|
|
|
child: Text(
|
|
|
|
item['title'],
|
|
|
|
style: const TextStyle(fontSize: 14),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
|
|
|
|
subtitle: Text(
|
|
|
|
item['time'],
|
|
|
|
style: TextStyle(fontSize: 13),
|
|
|
|
),
|
|
|
|
|
|
|
|
trailing: Container(
|
|
|
|
constraints: const BoxConstraints(minHeight: 100), // 确保最小高度
|
|
|
|
|
|
|
|
child: Column(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
mainAxisSize: MainAxisSize.min, // 关键修改:使用最小尺寸
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
|
children: [
|
|
|
|
Text(
|
|
|
|
item['read'] ? '已读' : '未读',
|
|
|
|
style: TextStyle(
|
|
|
|
fontSize: 12, // 稍微减小字体大小
|
|
|
|
color: item['read'] ? Colors.grey : Colors.red,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
SizedBox(height: 15,),
|
|
|
|
|
|
|
|
if (item['read'])
|
|
|
|
SizedBox(
|
|
|
|
height: 24, // 固定按钮高度
|
|
|
|
child: TextButton(
|
|
|
|
onPressed: () {},
|
|
|
|
child: const Text(
|
|
|
|
'删除',
|
|
|
|
style: TextStyle(fontSize: 13, color: Colors.white),
|
|
|
|
),
|
|
|
|
style: TextButton.styleFrom(
|
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
|
|
|
backgroundColor: Colors.red,
|
|
|
|
shape: RoundedRectangleBorder(
|
|
|
|
borderRadius: BorderRadius.circular(12),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|