調整成API方式,關閉延遲
This commit is contained in:
parent
2bd6731f9c
commit
8fe8e7113c
181
lib/announcement.dart
Normal file
181
lib/announcement.dart
Normal file
@ -0,0 +1,181 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Announcement {
|
||||
final String date;
|
||||
final String title;
|
||||
final String preview;
|
||||
final String full;
|
||||
|
||||
Announcement({
|
||||
required this.date,
|
||||
required this.title,
|
||||
required this.preview,
|
||||
required this.full,
|
||||
});
|
||||
|
||||
factory Announcement.fromJson(Map<String, dynamic> json) {
|
||||
return Announcement(
|
||||
date: json['date'],
|
||||
title: json['title'],
|
||||
preview: json['preview'],
|
||||
full: json['full'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AnnouncementWrapper extends StatefulWidget {
|
||||
const AnnouncementWrapper({super.key});
|
||||
|
||||
@override
|
||||
State<AnnouncementWrapper> createState() => _AnnouncementWrapperState();
|
||||
}
|
||||
|
||||
class _AnnouncementWrapperState extends State<AnnouncementWrapper> {
|
||||
List<Announcement> _announcements = [];
|
||||
bool _isLoading = true;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_fetchAnnouncements();
|
||||
}
|
||||
|
||||
Future<void> _fetchAnnouncements() async {
|
||||
// 模擬 API 延遲
|
||||
//await Future.delayed(const Duration(milliseconds: 100));
|
||||
|
||||
// 模擬 API 回傳資料
|
||||
final mockData = [
|
||||
{
|
||||
'date': '2025/04/28',
|
||||
'title': '水塔清洗通知',
|
||||
'preview': '本社區將於 2025/05/05 進行水塔清洗作業,請住戶提前儲水...',
|
||||
'full': '本社區將於 2025/05/05 進行水塔清洗作業,請住戶提前儲水,造成不便敬請見諒。',
|
||||
},
|
||||
{
|
||||
'date': '2025/04/25',
|
||||
'title': '停電通知',
|
||||
'preview': '台電預計於 5/1 上午進行電路維修,期間將暫時停電,請提前準備...',
|
||||
'full': '台電預計於 2025/05/01 08:00~12:00 進行電路維修,期間將暫時停電,請提前準備。',
|
||||
},
|
||||
{
|
||||
'date': '2025/04/20',
|
||||
'title': '消防演練公告',
|
||||
'preview': '消防演練將於 5/10 下午舉行,請住戶配合參與並聆聽安全說明...',
|
||||
'full': '消防演練將於 2025/05/10 下午 3 點舉行,請各位住戶配合參與。',
|
||||
},
|
||||
];
|
||||
|
||||
setState(() {
|
||||
_announcements =
|
||||
mockData.map((json) => Announcement.fromJson(json)).toList();
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
void _showDetailModal(BuildContext context, String title, String content) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder:
|
||||
(_) => AlertDialog(
|
||||
title: Text(title),
|
||||
content: Text(content),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: const Text('關閉'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24),
|
||||
child:
|
||||
_isLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
const Expanded(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'公告列表',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 48),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
const Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text('📢 最新公告', style: TextStyle(fontSize: 16)),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
..._announcements.map(
|
||||
(item) => Column(
|
||||
children: [
|
||||
ListTile(
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
item.date,
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.black54,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
item.title,
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
subtitle: Padding(
|
||||
padding: const EdgeInsets.only(top: 6.0),
|
||||
child: Text(
|
||||
item.preview,
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
color: Colors.black45,
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap:
|
||||
() => _showDetailModal(
|
||||
context,
|
||||
item.title,
|
||||
item.full,
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user