feat(app): 初始化家庭网络监控Flutter应用基本结构

- 添加Flutter项目基础文件与配置,包括.gitignore和analysis_options.yaml
- 配置Android相关文件及Gradle构建脚本支持
- 新增设备状态与网络状态数据模型及相关枚举
- 实现网络检测及网速测试服务
- 创建监控状态管理Provider,实现设备状态管理和自动刷新机制
- 编写主界面HomeScreen,包括设备列表、网速仪表盘及基础交互
- 添加资源文件支持应用图标和启动画面
- 配置项目元数据文件,支持Flutter迁移及版本控制
- 新增项目README,提供入门指引和相关资源链接
This commit is contained in:
2025-12-08 09:01:47 +08:00
parent 360cb1a991
commit 6a0d84f063
76 changed files with 4153 additions and 0 deletions

View File

@@ -0,0 +1,199 @@
import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';
import '../models/models.dart';
/// 网速仪表盘组件
class SpeedGauge extends StatelessWidget {
final NetworkStatus networkStatus;
final bool isLoading;
const SpeedGauge({
super.key,
required this.networkStatus,
this.isLoading = false,
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Card(
margin: const EdgeInsets.all(16),
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: [
Text(
'网络状态',
style: theme.textTheme.titleLarge,
),
const SizedBox(height: 20),
if (isLoading)
const SizedBox(
height: 120,
child: Center(
child: CircularProgressIndicator(),
),
)
else
_buildSpeedDisplay(context),
const SizedBox(height: 16),
_buildConnectionInfo(context),
],
),
),
);
}
Widget _buildSpeedDisplay(BuildContext context) {
final theme = Theme.of(context);
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
// 下载速度
_SpeedIndicator(
label: '下载',
value: networkStatus.downloadSpeedText,
icon: Icons.download,
color: Colors.blue,
),
// 延迟
_SpeedIndicator(
label: '延迟',
value: networkStatus.latency >= 0
? '${networkStatus.latency}ms'
: '--',
icon: Icons.speed,
color: _getLatencyColor(networkStatus.latency),
),
// 上传速度
_SpeedIndicator(
label: '上传',
value: networkStatus.uploadSpeedText,
icon: Icons.upload,
color: Colors.green,
),
],
);
}
Widget _buildConnectionInfo(BuildContext context) {
final theme = Theme.of(context);
return Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: theme.colorScheme.surfaceContainerHighest.withValues(alpha: 0.5),
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_InfoItem(
label: '状态',
value: networkStatus.isConnected ? '已连接' : '未连接',
valueColor: networkStatus.isConnected ? Colors.green : Colors.red,
),
_InfoItem(
label: '本地IP',
value: networkStatus.localIp.isEmpty
? '--'
: networkStatus.localIp,
),
],
),
);
}
Color _getLatencyColor(int latency) {
if (latency < 0) return Colors.grey;
if (latency > 200) return Colors.red;
if (latency > 100) return Colors.orange;
return Colors.green;
}
}
/// 速度指示器
class _SpeedIndicator extends StatelessWidget {
final String label;
final String value;
final IconData icon;
final Color color;
const _SpeedIndicator({
required this.label,
required this.value,
required this.icon,
required this.color,
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Column(
children: [
Container(
width: 60,
height: 60,
decoration: BoxDecoration(
color: color.withValues(alpha: 0.1),
shape: BoxShape.circle,
),
child: Icon(icon, color: color, size: 28),
),
const SizedBox(height: 8),
Text(
value,
style: theme.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
Text(
label,
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
),
),
],
);
}
}
/// 信息项
class _InfoItem extends StatelessWidget {
final String label;
final String value;
final Color? valueColor;
const _InfoItem({
required this.label,
required this.value,
this.valueColor,
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Column(
children: [
Text(
label,
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
),
),
const SizedBox(height: 4),
Text(
value,
style: theme.textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.w500,
color: valueColor,
),
),
],
);
}
}