2025-12-29 First Commit

This commit is contained in:
DATAEXPRESS\4734
2025-12-29 15:20:40 +08:00
commit fb2603c6f0
92 changed files with 6006 additions and 0 deletions
+66
View File
@@ -0,0 +1,66 @@
import 'package:flutter/material.dart';
// 1. 確保引入 news_detail.dart
import '../News/news_detail.dart';
class News extends StatelessWidget {
final List<String> news;
// 構造函數保持不變
const News(this.news, {super.key});
@override
Widget build(BuildContext context) {
// 使用 ListView.builder 替代 Column 和 map().toList()
// 這樣可以確保內容可以捲動,並且只構建可見的項目,效率更高。
return ListView.builder(
// 設置列表的長度,即 news 列表的項目數
itemCount: news.length,
// 根據索引來構建每個列表項目
itemBuilder: (BuildContext context, int index) {
final String currentNewsTitle = news[index]; // 提取當前新聞標題
// 使用 news[index] 來取得對應的新聞文本
return Card(
elevation: 5, // 可選: 增加卡片陰影
margin: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0), // 增加邊距
// 在這裡可以選擇添加 Key
key: ValueKey(currentNewsTitle + index.toString()),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, // 讓圖片和文字可以寬度延伸
children: <Widget>[
// --- 點擊功能的修改在這裡 ---
GestureDetector(
onTap: () {
// 點擊事件:導航到 NewsDetail 畫面
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NewsDetail(
// 2. 將當前新聞的標題/內容傳遞給詳細頁面
newsTitle: currentNewsTitle,
),
),
);
},
child: Image.asset(
'assets/F16-02.jpg',
fit: BoxFit.cover,
height: 200,
),
),
// --------------------------
Padding(
padding: const EdgeInsets.all(12.0),
child: Text(
currentNewsTitle,
style: const TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),
),
),
],
),
);
},
);
}
}
+64
View File
@@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
// 這是一個 StatelessWidget,用於顯示單條新聞的詳細內容
class NewsDetail extends StatelessWidget {
final String newsTitle; // 接收從前一個畫面傳遞過來的新聞標題
// 為了演示,我們假設詳細內容是一個較長的文本
final String newsDetailContent =
"這是新聞的詳細內容。它包含了更深入的分析、更多的數據和完整的背景資訊。點擊圖片後,使用者可以在這個頁面仔細閱讀。由於這是一個範例,我們使用了一些重複的文本來模擬文章長度,以確保頁面可以滾動。在這個頁面,您可以加入更多的元素,例如不同的圖片、作者資訊、發布日期等。";
const NewsDetail({required this.newsTitle, super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
// 設置 App Bar,標題可以是傳入的新聞標題
appBar: AppBar(
title: Text(newsTitle, overflow: TextOverflow.ellipsis), // 防止標題過長
),
// 使用 SingleChildScrollView 確保頁面內容超出螢幕時可以滾動
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// 再次顯示圖片 (可選)
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.asset(
'assets/F16-02.jpg',
fit: BoxFit.cover,
height: 250,
width: double.infinity, // 佔滿寬度
),
),
const SizedBox(height: 16.0),
// 顯示新聞標題
Text(
newsTitle,
style: const TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.w800,
),
),
const Divider(height: 32.0), // 分隔線
// 顯示新聞詳細內容
Text(
newsDetailContent * 5, // 重複內容 5 次來模擬長文章
style: const TextStyle(
fontSize: 16.0,
height: 1.5, // 增加行高,改善閱讀體驗
),
textAlign: TextAlign.justify, // 內容兩端對齊
),
],
),
),
),
);
}
}
+87
View File
@@ -0,0 +1,87 @@
import 'package:flutter/material.dart';
// 確保你的 news.dart 文件和 News 類已經被正確引入
import 'news.dart';
// 確保引入 MainMenu 所在的 main.dart 文件,以便導航
import '../main.dart';
class NewsManager extends StatefulWidget {
const NewsManager({super.key});
@override
State<StatefulWidget> createState() {
return _NewsManagerState();
}
}
class _NewsManagerState extends State<NewsManager> {
List<String> news = ['第一筆資料: F-16 戰機升級計畫', '第二筆資料: 台積電研發新突破'];
void _addNews() {
setState(() {
news.add('新增資料:最新動態 ${DateTime.now().second}');
});
}
// 新增的導航函數:返回到主選單
void _backToHome() {
// Navigator.popUntil 會一直彈出 (Pop) 路由堆棧中的頁面,直到遇到一個
// 滿足條件 (predicte) 的路由。在這裡,我們使用 (route) => route.isFirst
// 來返回到路由堆棧中的第一個頁面,也就是 MainMenu (如果您的啟動順序是 Login -> MainMenu)。
// 如果 MainMenu 不是第一個頁面,您可以考慮使用:
// Navigator.popUntil(context, ModalRoute.withName('/main_menu'));
// 但這需要您在 MaterialApp 中為 MainMenu 設定路由名稱。
// 最保險且簡單的方法是直接彈出所有,然後重新推入 MainMenu(確保 MainMenu 不會有歷史記錄)
// 或者我們假設 MainMenu 是 Login 成功後的第一個頁面,使用 pushReplacement 清理過的堆棧。
// 在本例中,我們直接導航回 MainMenu,並清除所有在它之上的頁面。
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => const MainMenu()),
(Route<dynamic> route) => false, // 移除所有前面的路由
);
// 註:若 NewsManager 已經是 Scaffold 的子頁面,使用 Navigator.pop(context)
// 即可返回上一個頁面(即 MainMenu)。但如果想確保是回主頁,用 pushAndRemoveUntil 更明確。
}
@override
Widget build(BuildContext context) {
// *** 關鍵修改:將整個頁面包裹在 Scaffold 中以包含 AppBar ***
return Scaffold(
appBar: AppBar(
title: const Text('公告事項'),
// ----------------------------------------------------
// 新增的返回主頁按鈕
actions: <Widget>[
IconButton(
icon: const Icon(Icons.home), // 使用一個 Home 圖標
tooltip: '返回主頁', // 長按時的提示
onPressed: _backToHome, // 點擊時呼叫導航函數
),
],
// ----------------------------------------------------
),
body: Column(
children: <Widget>[
// 1. 固定高度的按鈕部分
Container(
margin: const EdgeInsets.all(10),
child: ElevatedButton(
onPressed: _addNews,
child: const Text(
'新增資料',
style: TextStyle(fontSize: 20, color: Colors.redAccent),
),
),
),
// 2. 佔據剩餘空間的列表部分
Expanded(
child: News(news),
),
],
),
);
}
}