Files
home/home_monitor/lib/widgets/device_tile.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

155 lines
3.8 KiB
Dart

import 'package:flutter/material.dart';
import '../models/models.dart';
/// 设备列表项组件
class DeviceTile extends StatelessWidget {
final DeviceStatus device;
final VoidCallback? onTap;
final VoidCallback? onRefresh;
const DeviceTile({
super.key,
required this.device,
this.onTap,
this.onRefresh,
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final statusColor = _getStatusColor();
return Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
child: ListTile(
onTap: onTap,
leading: Container(
width: 48,
height: 48,
decoration: BoxDecoration(
color: statusColor.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(12),
),
child: Icon(
_getDeviceIcon(),
color: statusColor,
),
),
title: Text(
device.name,
style: theme.textTheme.titleMedium,
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${device.ip}:${device.port}',
style: theme.textTheme.bodySmall,
),
const SizedBox(height: 4),
Row(
children: [
_StatusBadge(
status: _getStatusText(),
color: statusColor,
),
if (device.latency != null) ...[
const SizedBox(width: 8),
Text(
'${device.latency}ms',
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
),
),
],
],
),
],
),
trailing: IconButton(
icon: const Icon(Icons.refresh),
onPressed: onRefresh,
tooltip: '刷新',
),
isThreeLine: true,
),
);
}
IconData _getDeviceIcon() {
switch (device.type) {
case DeviceType.gateway:
return Icons.router;
case DeviceType.bypass:
return Icons.alt_route;
case DeviceType.nas:
return Icons.storage;
case DeviceType.server:
return Icons.dns;
case DeviceType.camera:
return Icons.videocam;
case DeviceType.printer:
return Icons.print;
case DeviceType.other:
return Icons.devices;
}
}
Color _getStatusColor() {
switch (device.state) {
case DeviceState.online:
return Colors.green;
case DeviceState.offline:
return Colors.red;
case DeviceState.warning:
return Colors.orange;
case DeviceState.unknown:
return Colors.grey;
}
}
String _getStatusText() {
switch (device.state) {
case DeviceState.online:
return '在线';
case DeviceState.offline:
return '离线';
case DeviceState.warning:
return '警告';
case DeviceState.unknown:
return '未知';
}
}
}
/// 状态徽章
class _StatusBadge extends StatelessWidget {
final String status;
final Color color;
const _StatusBadge({
required this.status,
required this.color,
});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
decoration: BoxDecoration(
color: color.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(10),
border: Border.all(color: color.withValues(alpha: 0.3)),
),
child: Text(
status,
style: TextStyle(
color: color,
fontSize: 12,
fontWeight: FontWeight.w500,
),
),
);
}
}