Browse Source

feat(OTA升级页面): 重构并优化OTA升级页面UI和交互

- 将设备信息卡片重构为独立组件,添加渐变背景和阴影效果
- 优化版本信息展示样式,增加NEW标签和状态指示器
- 改进加载、错误和进度指示器的视觉设计
- 使用响应式单位(.w/.h)替代固定尺寸
- 增强暗黑模式下的视觉表现
weicu
lxm 1 year ago
parent
commit
121b4ae8d6
  1. 851
      lib/modules/ota_upgrade/views/ota_upgrade_view.dart

851
lib/modules/ota_upgrade/views/ota_upgrade_view.dart

@ -89,33 +89,17 @@ class OtaUpgradeView extends GetView<OtaUpgradeController> {
),
body: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(20),
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 16.h),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// 设备信息卡片
Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
color: isDarkMode ? Colors.grey[900] : Colors.white,
child: Padding(
padding: EdgeInsets.all(20),
child: Column(
children: [
_buildDeviceIcon(isDarkMode),
SizedBox(height: 20),
_buildVersionInfo(isDarkMode),
],
),
),
),
SizedBox(height: 20),
// 设备信息卡片 - 优化后的版本
_buildDeviceCard(isDarkMode),
SizedBox(height: 24.h),
// 更新说明
_buildUpdateNotes(isDarkMode),
SizedBox(height: 20),
// 更新说明 - 当有可用更新时显示
//_buildUpdateNotes(isDarkMode),
SizedBox(height: 16.h),
// 状态显示区域
Obx(() {
@ -135,257 +119,696 @@ class OtaUpgradeView extends GetView<OtaUpgradeController> {
);
}
// 设备信息卡片
Widget _buildDeviceCard(bool isDarkMode) {
return Container(
width: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: isDarkMode
? [
const Color(0xFF1A1A1A).withValues(alpha: 0.9),
const Color(0xFF2A2A2A).withValues(alpha: 0.9),
]
: [
const Color(0xFFF8FAFF),
const Color(0xFFE3F2FD),
],
),
borderRadius: BorderRadius.circular(20.r),
boxShadow: [
BoxShadow(
color: isDarkMode
? Colors.black.withValues(alpha: 0.3)
: Colors.black.withValues(alpha: 0.08),
blurRadius: 20,
offset: const Offset(0, 8),
spreadRadius: 0,
),
],
),
child: Padding(
padding: EdgeInsets.all(24.w),
child: Column(
children: [
// 设备图标区域
_buildDeviceIcon(isDarkMode),
SizedBox(height: 24.h),
// 版本信息区域
_buildVersionInfo(isDarkMode),
],
),
),
);
}
// 设备图标
Widget _buildDeviceIcon(bool isDarkMode) => Image.asset(
Widget _buildDeviceIcon(bool isDarkMode) {
return Container(
padding: EdgeInsets.all(20.w),
decoration: BoxDecoration(
color: isDarkMode
? Colors.white.withValues(alpha: 0.05)
: Colors.white.withValues(alpha: 0.7),
borderRadius: BorderRadius.circular(16.r),
border: Border.all(
color: isDarkMode
? Colors.white.withValues(alpha: 0.1)
: Colors.blue.withValues(alpha: 0.1),
width: 1,
),
),
child: Image.asset(
isDarkMode
? 'assets/images/headphone_dark.png'
: 'assets/images/headphone_light.png',
height: 180.h,
height: 120.h,
fit: BoxFit.contain,
);
),
);
}
Widget _buildVersionInfo(bool isDarkMode) => Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
// 版本信息显示
Widget _buildVersionInfo(bool isDarkMode) {
return Column(
children: [
// 当前版本信息
_buildVersionInfoRow(
label: '当前固件版本'.tr,
version: controller.currentVersion,
isDarkMode: isDarkMode,
isLatest: false,
),
SizedBox(height: 16.h),
// 最新版本信息
_buildVersionInfoRow(
label: '最新固件版本'.tr,
version: controller.latestVersion,
isDarkMode: isDarkMode,
isLatest: true,
),
// 版本状态指示器
SizedBox(height: 20.h),
_buildVersionStatusIndicator(isDarkMode),
],
);
}
// 版本信息行组件
Widget _buildVersionInfoRow({
required String label,
required RxString version,
required bool isDarkMode,
required bool isLatest,
}) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h),
decoration: BoxDecoration(
color: isDarkMode
? Colors.white.withValues(alpha: 0.03)
: Colors.white.withValues(alpha: 0.8),
borderRadius: BorderRadius.circular(12.r),
border: Border.all(
color: isDarkMode
? Colors.white.withValues(alpha: 0.08)
: Colors.grey.withValues(alpha: 0.2),
width: 1,
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center, // 改为center对齐
Text(
label,
style: TextStyle(
fontSize: 14.sp,
color: isDarkMode ? Colors.grey[300] : Colors.grey[700],
fontWeight: FontWeight.w500,
),
),
Obx(() => Row(
children: [
if (isLatest && controller.isUpdateAvailable.value) ...[
Container(
padding: EdgeInsets.symmetric(horizontal: 6.w, vertical: 2.h),
decoration: BoxDecoration(
color: Colors.orange.withValues(alpha: 0.2),
borderRadius: BorderRadius.circular(8.r),
),
child: Text(
'NEW',
style: TextStyle(
fontSize: 10.sp,
fontWeight: FontWeight.bold,
color: Colors.orange,
),
),
),
SizedBox(width: 8.w),
],
Text(
'V ${version.value}',
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: isDarkMode
? (isLatest ? Colors.green[300] : Colors.blue[300])
: (isLatest ? Colors.green[600] : Colors.blue[600]),
),
),
],
)),
],
),
);
}
// 版本状态指示器
Widget _buildVersionStatusIndicator(bool isDarkMode) {
return Obx(() {
if (controller.isUpdateAvailable.value) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.orange.withValues(alpha: 0.1),
Colors.red.withValues(alpha: 0.1),
],
),
borderRadius: BorderRadius.circular(20.r),
border: Border.all(
color: Colors.orange.withValues(alpha: 0.3),
width: 1,
),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text('当前固件版本:'.tr,
style: TextStyle(
fontSize: 18,
color: isDarkMode ? Colors.grey[300] : Colors.black)),
SizedBox(width: 8), // 改为width
Obx(() => Text('V ${controller.currentVersion}',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.normal,
color: isDarkMode ? Colors.blue[300] : Colors.blue))),
Icon(
Icons.update,
size: 16.sp,
color: Colors.orange,
),
SizedBox(width: 6.w),
Text(
'发现新版本',
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.w500,
color: Colors.orange,
),
),
],
),
SizedBox(height: 8), // 改为height
Row(
crossAxisAlignment: CrossAxisAlignment.center, // 改为center对齐
);
} else {
return Container(
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
decoration: BoxDecoration(
color: Colors.green.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(20.r),
border: Border.all(
color: Colors.green.withValues(alpha: 0.3),
width: 1,
),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text('最新固件版本:'.tr,
style: TextStyle(
fontSize: 18,
color: isDarkMode ? Colors.grey[300] : Colors.black)),
SizedBox(width: 8), // 改为width
Obx(() => Text('V ${controller.latestVersion}',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.normal,
color: isDarkMode ? Colors.blue[300] : Colors.blue))),
Icon(
Icons.check_circle,
size: 16.sp,
color: Colors.green,
),
SizedBox(width: 6.w),
Text(
'已是最新版本',
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.w500,
color: Colors.green,
),
),
],
),
],
);
);
}
});
}
// 添加固件更新说明
Widget _buildUpdateNotes(bool isDarkMode) =>
Obx(() => controller.isUpdateAvailable.value
? Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
// 固件更新说明
Widget _buildUpdateNotes(bool isDarkMode) {
return Obx(() => controller.isUpdateAvailable.value &&
controller.updatedescription.value.isNotEmpty
? Container(
width: double.infinity,
margin: EdgeInsets.only(bottom: 8.h),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: isDarkMode
? [
Colors.amber[900]!.withValues(alpha: 0.1),
Colors.orange[900]!.withValues(alpha: 0.05),
]
: [
Colors.amber[50]!,
Colors.orange[100]!.withValues(alpha: 0.3),
],
),
color: isDarkMode ? Colors.grey[900] : Colors.white,
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
borderRadius: BorderRadius.circular(16.r),
border: Border.all(
color: isDarkMode
? Colors.amber[700]!.withValues(alpha: 0.3)
: Colors.amber[200]!.withValues(alpha: 0.5),
width: 1,
),
),
child: Padding(
padding: EdgeInsets.all(20.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
padding: EdgeInsets.all(8.w),
decoration: BoxDecoration(
color: Colors.amber.withValues(alpha: 0.2),
borderRadius: BorderRadius.circular(8.r),
),
child: Icon(
Icons.new_releases,
color: isDarkMode ? Colors.amber[300] : Colors.amber,
size: 20,
color: isDarkMode ? Colors.amber[300] : Colors.amber[700],
size: 18.sp,
),
SizedBox(width: 8),
Text(
'更新内容'.tr,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: isDarkMode ? Colors.white : Colors.black,
),
),
SizedBox(width: 12.w),
Text(
'更新内容'.tr,
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: isDarkMode ? Colors.amber[200] : Colors.amber[800],
),
],
),
],
),
SizedBox(height: 16.h),
Container(
width: double.infinity,
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: isDarkMode
? Colors.white.withValues(alpha: 0.03)
: Colors.white.withValues(alpha: 0.7),
borderRadius: BorderRadius.circular(12.r),
),
Divider(),
SizedBox(height: 8),
// 这里可以从controller中获取更新说明,如果有的话
Text(
child: Text(
controller.updatedescription.value,
style: TextStyle(
fontSize: 14,
color: isDarkMode ? Colors.grey[300] : Colors.grey[800],
fontSize: 14.sp,
height: 1.5,
color: isDarkMode ? Colors.grey[300] : Colors.grey[700],
),
),
],
),
),
],
),
)
: SizedBox.shrink());
),
)
: const SizedBox.shrink());
}
Widget _buildLoadingIndicator(bool isDarkMode) => Column(
// 加载指示器
Widget _buildLoadingIndicator(bool isDarkMode) {
return Container(
padding: EdgeInsets.all(32.w),
decoration: BoxDecoration(
color: isDarkMode
? Colors.white.withValues(alpha: 0.03)
: Colors.white.withValues(alpha: 0.8),
borderRadius: BorderRadius.circular(20.r),
border: Border.all(
color: isDarkMode
? Colors.white.withValues(alpha: 0.08)
: Colors.grey.withValues(alpha: 0.2),
width: 1,
),
),
child: Column(
children: [
CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(
isDarkMode ? Colors.blue[300] : Colors.blue),
// 自定义加载动画
SizedBox(
width: 50.w,
height: 50.w,
child: CircularProgressIndicator(
strokeWidth: 3,
valueColor: AlwaysStoppedAnimation(
isDarkMode ? const Color(0xFF0066CC) : Colors.blue,
),
backgroundColor: isDarkMode
? Colors.white.withValues(alpha: 0.1)
: Colors.grey.withValues(alpha: 0.2),
),
),
SizedBox(height: 24.h),
Text(
'正在获取设备信息...',
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w500,
color: isDarkMode ? Colors.grey[300] : Colors.grey[700],
),
),
SizedBox(height: 8.h),
Text(
'请保持设备连接',
style: TextStyle(
fontSize: 12.sp,
color: isDarkMode ? Colors.grey[500] : Colors.grey[500],
),
),
SizedBox(height: 20),
Text('正在获取设备信息...',
style:
TextStyle(color: isDarkMode ? Colors.grey[300] : Colors.grey))
],
);
),
);
}
Widget _buildErrorInfo(bool isDarkMode) => Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color:
isDarkMode ? Colors.red[900]!.withOpacity(0.2) : Colors.red[50],
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: isDarkMode ? Colors.red[700]! : Colors.red[200]!,
width: 1,
),
// 错误信息显示
Widget _buildErrorInfo(bool isDarkMode) {
return Container(
padding: EdgeInsets.all(24.w),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: isDarkMode
? [
Colors.red[900]!.withValues(alpha: 0.15),
Colors.red[800]!.withValues(alpha: 0.1),
]
: [
Colors.red[50]!,
Colors.red[100]!.withValues(alpha: 0.3),
],
),
child: Column(
children: [
Icon(Icons.error_outline, color: Colors.red, size: 40),
SizedBox(height: 10),
Text(controller.errorMessage.value,
textAlign: TextAlign.center,
borderRadius: BorderRadius.circular(20.r),
border: Border.all(
color: isDarkMode
? Colors.red[700]!.withValues(alpha: 0.3)
: Colors.red[200]!.withValues(alpha: 0.5),
width: 1,
),
),
child: Column(
children: [
// 错误图标
Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.red.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(50.r),
),
child: Icon(
Icons.error_outline,
color: Colors.red,
size: 32.sp,
),
),
SizedBox(height: 16.h),
// 错误标题
Text(
'连接失败',
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.w600,
color: isDarkMode ? Colors.red[300] : Colors.red[700],
),
),
SizedBox(height: 8.h),
// 错误信息
Text(
controller.errorMessage.value,
textAlign: TextAlign.center,
style: TextStyle(
color: isDarkMode ? Colors.red[200] : Colors.red[600],
fontSize: 14.sp,
height: 1.4,
),
),
SizedBox(height: 24.h),
// 重试按钮
SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
icon: Icon(Icons.refresh, size: 18.sp),
label: Text(
'重试连接'.tr,
style: TextStyle(
color: isDarkMode ? Colors.red[300] : Colors.red,
fontSize: 16)),
SizedBox(height: 20),
ElevatedButton.icon(
icon: Icon(Icons.refresh),
label: Text('重试连接'.tr),
fontSize: 16.sp,
fontWeight: FontWeight.w500,
),
),
style: ElevatedButton.styleFrom(
backgroundColor: isDarkMode ? Colors.blue[700] : Colors.blue,
backgroundColor: isDarkMode ? const Color(0xFF0066CC) : Colors.blue,
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
padding: EdgeInsets.symmetric(vertical: 14.h),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.r),
),
elevation: 0,
),
onPressed: controller.retryConnection,
)
],
),
);
),
),
],
),
);
}
// 更新按钮
Widget _buildUpdateButton(bool isDarkMode) {
return controller.isUpgrade.value
? _buildProgressIndicator(isDarkMode)
: Container(
width: double.infinity,
padding: EdgeInsets.symmetric(vertical: 10),
child: Column(
children: [
ElevatedButton.icon(
icon: Icon(
controller.isUpdateAvailable.value
? Icons.system_update
: Icons.check_circle,
return Obx(() {
if (controller.isUpgrade.value) {
return _buildProgressIndicator(isDarkMode);
}
return SizedBox(
width: double.infinity,
child: Column(
children: [
// 主要更新按钮
Container(
width: double.infinity,
height: 56.h,
decoration: BoxDecoration(
gradient: controller.isUpdateAvailable.value
? LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: isDarkMode
? [const Color(0xFF0066CC), const Color(0xFF0052A3)]
: [Colors.blue, Colors.blue[700]!],
)
: null,
color: !controller.isUpdateAvailable.value
? (isDarkMode ? Colors.grey[800] : Colors.grey[300])
: null,
borderRadius: BorderRadius.circular(16.r),
boxShadow: controller.isUpdateAvailable.value
? [
BoxShadow(
color: Colors.blue.withValues(alpha: 0.3),
blurRadius: 12,
offset: const Offset(0, 4),
),
]
: null,
),
child: ElevatedButton.icon(
icon: Icon(
controller.isUpdateAvailable.value
? Icons.system_update
: Icons.check_circle,
size: 20.sp,
),
label: Text(
controller.isUpdateAvailable.value ? '立即更新' : '已是最新版本',
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
),
label: Text(
controller.isUpdateAvailable.value ? '立即更新' : '已是最新版本',
style: TextStyle(fontSize: 16),
),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.transparent,
foregroundColor: Colors.white,
shadowColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.r),
),
style: ElevatedButton.styleFrom(
backgroundColor: controller.isUpdateAvailable.value
? (isDarkMode ? Colors.blue[700] : Colors.blue)
: (isDarkMode ? Colors.grey[800] : Colors.grey),
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 40, vertical: 15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
minimumSize: Size(240, 50),
),
onPressed: controller.isUpdateAvailable.value
? controller.startUpdate
: null,
),
),
// 更新提示信息
if (controller.isUpdateAvailable.value) ...[
SizedBox(height: 16.h),
Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: isDarkMode
? Colors.orange.withValues(alpha: 0.1)
: Colors.orange[50],
borderRadius: BorderRadius.circular(12.r),
border: Border.all(
color: Colors.orange.withValues(alpha: 0.3),
width: 1,
),
onPressed: controller.isUpdateAvailable.value
? controller.startUpdate
: null,
),
if (controller.isUpdateAvailable.value) ...[
SizedBox(height: 8),
Text(
'取出双耳机,并保证电量均为30%以上的状态'.tr,
style: TextStyle(
fontSize: 14,
color: isDarkMode ? Colors.grey[400] : Colors.grey[600],
child: Row(
children: [
Icon(
Icons.info_outline,
color: Colors.orange,
size: 20.sp,
),
),
],
],
),
);
SizedBox(width: 12.w),
Expanded(
child: Text(
'取出双耳机,并保证电量均为30%以上的状态'.tr,
style: TextStyle(
fontSize: 13.sp,
color: isDarkMode ? Colors.orange[200] : Colors.orange[800],
height: 1.3,
),
),
),
],
),
),
],
],
),
);
});
}
// 进度指示器
Widget _buildProgressIndicator(bool isDarkMode) {
return Obx(() {
final progress = controller.progress.value;
final type = controller.type.value;
// // 处理升级失败状态:弹出 snackbar 并显示错误提示
// if (type == OtaUpgradeController.UPGRADE_FAILED ||
// type == OtaUpgradeController.CONNECTION_DISCONNECTION) {
// // 使用延迟确保在 build 完成后执行
// Future.delayed(Duration.zero, () {
// Get.snackbar('升级失败', '重新连接设备后重试');
// });
// return Container(
// width: double.infinity,
// padding: const EdgeInsets.symmetric(vertical: 10),
// child: Text(
// '升级失败,请重新连接设备',
// style: TextStyle(
// fontSize: 18,
// fontWeight: FontWeight.bold,
// color: Colors.red[700],
// ),
// ),
// );
// }
final statusMessage = controller.getStatusMessage(type);
// 正常升级状态
return Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 10),
padding: EdgeInsets.all(24.w),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: isDarkMode
? [
const Color(0xFF1A1A1A).withValues(alpha: 0.9),
const Color(0xFF2A2A2A).withValues(alpha: 0.9),
]
: [
const Color(0xFFF8FAFF),
const Color(0xFFE3F2FD),
],
),
borderRadius: BorderRadius.circular(20.r),
boxShadow: [
BoxShadow(
color: isDarkMode
? Colors.black.withValues(alpha: 0.3)
: Colors.black.withValues(alpha: 0.08),
blurRadius: 20,
offset: const Offset(0, 8),
),
],
),
child: Column(
children: [
Text(
controller.getStatusMessage(type),
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: isDarkMode ? Colors.blue[300] : Colors.blue[700],
),
// 状态图标和文字
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.all(8.w),
decoration: BoxDecoration(
color: Colors.blue.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(8.r),
),
child: Icon(
Icons.system_update,
color: isDarkMode ? const Color(0xFF0066CC) : Colors.blue,
size: 20.sp,
),
),
SizedBox(width: 12.w),
Text(
statusMessage,
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.w600,
color: isDarkMode ? Colors.blue[300] : Colors.blue[700],
),
),
],
),
const SizedBox(height: 16),
LinearProgressIndicator(
value: progress / 100.0, // 转换为 0.0-1.0
backgroundColor: isDarkMode ? Colors.grey[800] : Colors.grey[200],
valueColor: AlwaysStoppedAnimation<Color>(
isDarkMode ? Colors.blue[300]! : Colors.blue,
SizedBox(height: 24.h),
// 进度条容器
Container(
height: 8.h,
decoration: BoxDecoration(
color: isDarkMode
? Colors.white.withValues(alpha: 0.1)
: Colors.grey[200],
borderRadius: BorderRadius.circular(4.r),
),
),
const SizedBox(height: 8),
Text(
'${progress.toStringAsFixed(1)}%',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: isDarkMode ? Colors.blue[300] : Colors.blue[700],
child: ClipRRect(
borderRadius: BorderRadius.circular(4.r),
child: LinearProgressIndicator(
value: progress / 100.0,
backgroundColor: Colors.transparent,
valueColor: AlwaysStoppedAnimation<Color>(
isDarkMode ? const Color(0xFF0066CC) : Colors.blue,
),
),
),
),
SizedBox(height: 16.h),
// 进度百分比和详细信息
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${progress.toStringAsFixed(1)}%',
style: TextStyle(
fontSize: 24.sp,
fontWeight: FontWeight.bold,
color: isDarkMode ? Colors.blue[300] : Colors.blue[700],
),
),
Text(
'请勿断开连接',
style: TextStyle(
fontSize: 12.sp,
color: isDarkMode ? Colors.grey[400] : Colors.grey[600],
),
),
],
),
],
),
);

Loading…
Cancel
Save