Files
home/home_monitor/lib/screens/home_screen.dart
panw 6a0d84f063 feat(app): 初始化家庭网络监控Flutter应用基本结构
- 添加Flutter项目基础文件与配置,包括.gitignore和analysis_options.yaml
- 配置Android相关文件及Gradle构建脚本支持
- 新增设备状态与网络状态数据模型及相关枚举
- 实现网络检测及网速测试服务
- 创建监控状态管理Provider,实现设备状态管理和自动刷新机制
- 编写主界面HomeScreen,包括设备列表、网速仪表盘及基础交互
- 添加资源文件支持应用图标和启动画面
- 配置项目元数据文件,支持Flutter迁移及版本控制
- 新增项目README,提供入门指引和相关资源链接
2025-12-08 09:01:47 +08:00

260 lines
7.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/providers.dart';
import '../widgets/widgets.dart';
/// 主页面
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
void initState() {
super.initState();
// 初始化数据
WidgetsBinding.instance.addPostFrameCallback((_) {
final provider = context.read<MonitorProvider>();
provider.initDefaultDevices();
provider.refreshAll();
provider.startAutoRefresh(intervalSeconds: 30);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: _buildAppBar(),
body: _buildBody(),
floatingActionButton: _buildFAB(),
);
}
PreferredSizeWidget _buildAppBar() {
return AppBar(
title: const Text('家庭网络监控'),
centerTitle: true,
actions: [
Consumer<MonitorProvider>(
builder: (context, provider, _) {
return IconButton(
icon: provider.isLoading
? const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Icon(Icons.refresh),
onPressed: provider.isLoading ? null : () => provider.refreshAll(),
tooltip: '刷新',
);
},
),
IconButton(
icon: const Icon(Icons.settings),
onPressed: () {
_showSettingsDialog();
},
tooltip: '设置',
),
],
);
}
Widget _buildBody() {
return Consumer<MonitorProvider>(
builder: (context, provider, _) {
return RefreshIndicator(
onRefresh: () => provider.refreshAll(),
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 网速仪表盘
SpeedGauge(
networkStatus: provider.networkStatus,
isLoading: provider.isTestingSpeed,
),
// 概览卡片
_buildOverviewCards(provider),
// 设备列表标题
Padding(
padding: const EdgeInsets.fromLTRB(16, 16, 16, 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'监控设备',
style: Theme.of(context).textTheme.titleMedium,
),
TextButton.icon(
onPressed: () => _showAddDeviceDialog(),
icon: const Icon(Icons.add, size: 18),
label: const Text('添加'),
),
],
),
),
// 设备列表
_buildDeviceList(provider),
const SizedBox(height: 80),
],
),
),
);
},
);
}
Widget _buildOverviewCards(MonitorProvider provider) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
children: [
Expanded(
child: StatusCard(
title: '在线设备',
value: '${provider.onlineDevicesCount}',
icon: Icons.check_circle,
iconColor: Colors.green,
subtitle: '${provider.devices.length} 台设备',
),
),
const SizedBox(width: 12),
Expanded(
child: StatusCard(
title: '离线设备',
value: '${provider.offlineDevicesCount}',
icon: Icons.error,
iconColor: provider.offlineDevicesCount > 0
? Colors.red
: Colors.grey,
subtitle: provider.offlineDevicesCount > 0
? '需要检查'
: '全部正常',
),
),
],
),
);
}
Widget _buildDeviceList(MonitorProvider provider) {
if (provider.devices.isEmpty) {
return const Center(
child: Padding(
padding: EdgeInsets.all(32),
child: Column(
children: [
Icon(Icons.devices, size: 64, color: Colors.grey),
SizedBox(height: 16),
Text('暂无监控设备'),
SizedBox(height: 8),
Text('点击右上角添加设备', style: TextStyle(color: Colors.grey)),
],
),
),
);
}
return ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: provider.devices.length,
itemBuilder: (context, index) {
final device = provider.devices[index];
return DeviceTile(
device: device,
onRefresh: () => provider.checkSingleDevice(device.id),
onTap: () => _showDeviceDetail(device),
);
},
);
}
Widget _buildFAB() {
return Consumer<MonitorProvider>(
builder: (context, provider, _) {
return FloatingActionButton.extended(
onPressed: provider.isTestingSpeed ? null : () => provider.runSpeedTest(),
icon: provider.isTestingSpeed
? const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
strokeWidth: 2,
color: Colors.white,
),
)
: const Icon(Icons.speed),
label: Text(provider.isTestingSpeed ? '测速中...' : '测速'),
);
},
);
}
void _showSettingsDialog() {
final provider = context.read<MonitorProvider>();
int interval = provider.refreshInterval;
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('设置'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: const Text('自动刷新间隔'),
subtitle: Text('$interval'),
trailing: DropdownButton<int>(
value: interval,
items: const [
DropdownMenuItem(value: 10, child: Text('10秒')),
DropdownMenuItem(value: 30, child: Text('30秒')),
DropdownMenuItem(value: 60, child: Text('1分钟')),
DropdownMenuItem(value: 300, child: Text('5分钟')),
],
onChanged: (value) {
if (value != null) {
provider.setRefreshInterval(value);
Navigator.pop(context);
}
},
),
),
],
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('关闭'),
),
],
),
);
}
void _showAddDeviceDialog() {
// TODO: 实现添加设备对话框
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('添加设备功能开发中...')),
);
}
void _showDeviceDetail(device) {
// TODO: 实现设备详情页
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('设备: ${device.name}')),
);
}
}