6 changed files with 727 additions and 771 deletions
File diff suppressed because it is too large
@ -0,0 +1,253 @@ |
|||||
|
import 'package:flutter/material.dart'; |
||||
|
import 'package:get/get.dart'; |
||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||
|
import '../controllers/pairing_controller.dart'; |
||||
|
import '../../../core/themes/app_theme.dart'; |
||||
|
|
||||
|
/// 配对视图 - 简化版本 |
||||
|
class PairingView extends GetView<PairingController> { |
||||
|
const PairingView({Key? key}) : super(key: key); |
||||
|
|
||||
|
@override |
||||
|
Widget build(BuildContext context) { |
||||
|
final bool isDarkMode = Theme.of(context).brightness == Brightness.dark; |
||||
|
|
||||
|
return Scaffold( |
||||
|
backgroundColor: isDarkMode ? Colors.black : Colors.white, |
||||
|
body: SafeArea( |
||||
|
child: Padding( |
||||
|
padding: EdgeInsets.all(24.w), |
||||
|
child: Column( |
||||
|
children: [ |
||||
|
// 顶部标题 |
||||
|
_buildHeader(isDarkMode), |
||||
|
|
||||
|
// 中间内容 |
||||
|
Expanded( |
||||
|
child: Center( |
||||
|
child: Obx(() => _buildContent(isDarkMode)), |
||||
|
), |
||||
|
), |
||||
|
|
||||
|
// 底部按钮 |
||||
|
Obx(() => _buildButtons(isDarkMode)), |
||||
|
|
||||
|
SizedBox(height: 20.h), |
||||
|
], |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
/// 构建标题 |
||||
|
Widget _buildHeader(bool isDarkMode) { |
||||
|
return Column( |
||||
|
children: [ |
||||
|
Text( |
||||
|
'设备配对', |
||||
|
style: TextStyle( |
||||
|
fontSize: 24.sp, |
||||
|
fontWeight: FontWeight.bold, |
||||
|
color: isDarkMode ? Colors.white : Colors.black, |
||||
|
), |
||||
|
), |
||||
|
SizedBox(height: 8.h), |
||||
|
Text( |
||||
|
'连接您的 DeepSound 耳机', |
||||
|
style: TextStyle( |
||||
|
fontSize: 14.sp, |
||||
|
color: isDarkMode ? Colors.grey[400] : Colors.grey[600], |
||||
|
), |
||||
|
), |
||||
|
SizedBox(height: 40.h), |
||||
|
], |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
/// 构建主要内容 |
||||
|
Widget _buildContent(bool isDarkMode) { |
||||
|
final state = controller.currentState; |
||||
|
final isLoading = controller.isLoading.value; |
||||
|
|
||||
|
return Column( |
||||
|
mainAxisSize: MainAxisSize.min, |
||||
|
children: [ |
||||
|
// 状态图标 |
||||
|
_buildStateIcon(state, isLoading, isDarkMode), |
||||
|
|
||||
|
SizedBox(height: 40.h), |
||||
|
|
||||
|
// 状态文本 |
||||
|
Text( |
||||
|
controller.statusText.value, |
||||
|
style: TextStyle( |
||||
|
fontSize: 16.sp, |
||||
|
color: isDarkMode ? Colors.white : Colors.black, |
||||
|
), |
||||
|
textAlign: TextAlign.center, |
||||
|
), |
||||
|
|
||||
|
// 错误详情 |
||||
|
if (state == PairingState.error) ...[ |
||||
|
SizedBox(height: 16.h), |
||||
|
Container( |
||||
|
padding: EdgeInsets.all(16.w), |
||||
|
decoration: BoxDecoration( |
||||
|
color: Colors.red.withOpacity(0.1), |
||||
|
borderRadius: BorderRadius.circular(12.r), |
||||
|
border: Border.all(color: Colors.red.withOpacity(0.3)), |
||||
|
), |
||||
|
child: Row( |
||||
|
children: [ |
||||
|
Icon( |
||||
|
Icons.error_outline, |
||||
|
color: Colors.red, |
||||
|
size: 20.sp, |
||||
|
), |
||||
|
SizedBox(width: 12.w), |
||||
|
Expanded( |
||||
|
child: Text( |
||||
|
controller.errorMessage, |
||||
|
style: TextStyle( |
||||
|
fontSize: 14.sp, |
||||
|
color: Colors.red, |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
), |
||||
|
], |
||||
|
], |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
/// 构建状态图标 |
||||
|
Widget _buildStateIcon(PairingState state, bool isLoading, bool isDarkMode) { |
||||
|
if (isLoading) { |
||||
|
return CircularProgressIndicator( |
||||
|
valueColor: AlwaysStoppedAnimation<Color>( |
||||
|
Theme.of(Get.context!).primaryColor, |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
IconData iconData; |
||||
|
Color iconColor; |
||||
|
|
||||
|
switch (state) { |
||||
|
case PairingState.idle: |
||||
|
case PairingState.checking: |
||||
|
iconData = Icons.bluetooth_searching; |
||||
|
iconColor = Colors.blue; |
||||
|
break; |
||||
|
|
||||
|
case PairingState.waitingClassic: |
||||
|
iconData = Icons.bluetooth; |
||||
|
iconColor = Colors.grey; |
||||
|
break; |
||||
|
|
||||
|
case PairingState.verifying: |
||||
|
iconData = Icons.verified_user; |
||||
|
iconColor = Colors.orange; |
||||
|
break; |
||||
|
|
||||
|
case PairingState.waitingBle: |
||||
|
iconData = Icons.sync; |
||||
|
iconColor = Colors.blue; |
||||
|
break; |
||||
|
|
||||
|
case PairingState.completed: |
||||
|
iconData = Icons.check_circle; |
||||
|
iconColor = Colors.green; |
||||
|
break; |
||||
|
|
||||
|
case PairingState.error: |
||||
|
iconData = Icons.error; |
||||
|
iconColor = Colors.red; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
return Container( |
||||
|
width: 100.w, |
||||
|
height: 100.w, |
||||
|
decoration: BoxDecoration( |
||||
|
color: iconColor.withOpacity(0.1), |
||||
|
shape: BoxShape.circle, |
||||
|
), |
||||
|
child: Icon( |
||||
|
iconData, |
||||
|
size: 60.sp, |
||||
|
color: iconColor, |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
/// 构建按钮 |
||||
|
Widget _buildButtons(bool isDarkMode) { |
||||
|
final showConnectButton = controller.showConnectButton.value; |
||||
|
final showRetryButton = controller.showRetryButton.value; |
||||
|
final showSkipButton = controller.showSkipButton.value; |
||||
|
|
||||
|
return Column( |
||||
|
children: [ |
||||
|
// 主要操作按钮 |
||||
|
if (showConnectButton) |
||||
|
_buildPrimaryButton( |
||||
|
'连接设备', |
||||
|
controller.onConnectTap, |
||||
|
isDarkMode, |
||||
|
), |
||||
|
|
||||
|
if (showRetryButton) |
||||
|
_buildPrimaryButton( |
||||
|
'重试', |
||||
|
controller.onRetryTap, |
||||
|
isDarkMode, |
||||
|
), |
||||
|
|
||||
|
SizedBox(height: 12.h), |
||||
|
|
||||
|
// 跳过按钮 |
||||
|
if (showSkipButton) |
||||
|
TextButton( |
||||
|
onPressed: controller.onSkipTap, |
||||
|
child: Text( |
||||
|
'跳过', |
||||
|
style: TextStyle( |
||||
|
fontSize: 14.sp, |
||||
|
color: isDarkMode ? Colors.grey[400] : Colors.grey[600], |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
], |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
/// 构建主要按钮 |
||||
|
Widget _buildPrimaryButton(String text, VoidCallback onPressed, bool isDarkMode) { |
||||
|
return SizedBox( |
||||
|
width: double.infinity, |
||||
|
height: 48.h, |
||||
|
child: ElevatedButton( |
||||
|
onPressed: onPressed, |
||||
|
style: ElevatedButton.styleFrom( |
||||
|
backgroundColor: Theme.of(Get.context!).primaryColor, |
||||
|
shape: RoundedRectangleBorder( |
||||
|
borderRadius: BorderRadius.circular(12.r), |
||||
|
), |
||||
|
elevation: 0, |
||||
|
), |
||||
|
child: Text( |
||||
|
text, |
||||
|
style: TextStyle( |
||||
|
fontSize: 16.sp, |
||||
|
fontWeight: FontWeight.w600, |
||||
|
color: Colors.white, |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue