import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import '../controllers/pairing_controller.dart'; import '../../../core/widgets/common_bottom_nav.dart'; import '../../../core/themes/app_theme.dart'; import 'package:permission_handler/permission_handler.dart'; class PairingView extends GetView { 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: Stack( children: [ // 主要内容 _buildMainContent(isDarkMode), ], ), ), bottomNavigationBar: Opacity( opacity: 0.5, // 保持半透明效果 child: const CommonBottomNav(currentIndex: 0), ), ); } // 主要内容 Widget _buildMainContent(bool isDarkMode) { return Padding( padding: EdgeInsets.fromLTRB(24.w, 40.h, 24.w, 24.h), child: SingleChildScrollView( child: Column( children: [ // 标题部分 _buildHeader(isDarkMode), // 设备动画 SizedBox(height: 40.h), _buildDeviceAnimation(), // 搜索状态 SizedBox(height: 40.h), _buildSearchStatus(isDarkMode), // 底部按钮 SizedBox(height: 60.h), _buildBottomButtons(isDarkMode), SizedBox(height: 80.h), // 留出底部导航的空间 ], ), ), ); } // 标题部分 Widget _buildHeader(bool isDarkMode) { return Column( children: [ Text( 'DeepVoice', style: TextStyle( fontSize: 24.sp, fontWeight: FontWeight.bold, color: isDarkMode ? Colors.white : Colors.black, ), ), SizedBox(height: 8.h), Text( '连接世界,超越声音', style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.white70 : Colors.black54, ), ), ], ); } // 设备动画 Widget _buildDeviceAnimation() { return SizedBox( width: 240.w, height: 240.w, child: Stack( alignment: Alignment.center, children: [ // 脉动动画背景 _buildPulseBackground(), // 耳机图片 _buildHeadphoneImage(), // 旋转加载指示器 _buildLoadingIndicator(), ], ), ); } // 脉动背景 Widget _buildPulseBackground() { return TweenAnimationBuilder( tween: Tween(begin: 0.8, end: 1.1), duration: const Duration(seconds: 2), curve: Curves.easeInOut, builder: (context, value, child) { return Transform.scale( scale: value, child: Container( width: 200.w, height: 200.w, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ const Color(0xFF0066CC).withOpacity(0.2), const Color(0xFF5E5CE6).withOpacity(0.2), ], ), shape: BoxShape.circle, ), ), ); }, ); } // 耳机图片 Widget _buildHeadphoneImage() { return Container( width: 140.w, height: 140.w, decoration: BoxDecoration( gradient: const LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Color(0xFF0066CC), Color(0xFF5E5CE6), ], ), shape: BoxShape.circle, ), child: Icon( Icons.headset, size: 80.sp, color: Colors.white, ), ); } // 加载指示器 Widget _buildLoadingIndicator() { return SizedBox( width: 180.w, height: 180.w, child: CircularProgressIndicator( strokeWidth: 4.w, valueColor: const AlwaysStoppedAnimation(Color(0xFF0066CC)), backgroundColor: const Color(0xFF0066CC).withOpacity(0.1), ), ); } // 搜索状态 Widget _buildSearchStatus(bool isDarkMode) { return Obx(() { final String status = controller.statusDescription; final bool hasDevice = controller.deviceInfo.isNotEmpty && controller.deviceInfo['device'] != null; final bool hasError = controller.errorMessage.isNotEmpty; // 已找到设备 if (hasDevice) { return Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.check_circle, color: Colors.green, size: 20.sp), SizedBox(width: 8.w), Text( '设备信息获取成功', style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.w600, color: Colors.green, ), ), ], ), SizedBox(height: 8.h), Text( '正在跳转到主页...', style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.white70 : Colors.black54, ), ), ], ); } // 有错误信息 if (hasError) { // 蓝牙关闭错误 if (status.contains('蓝牙已关闭')) { return Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.bluetooth_disabled, color: Colors.orange, size: 20.sp), SizedBox(width: 8.w), Text( '蓝牙已关闭', style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.w600, color: Colors.orange, ), ), ], ), SizedBox(height: 8.h), Text( controller.errorMessage, style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.white70 : Colors.black54, ), textAlign: TextAlign.center, ), ], ); } // 权限错误 if (status.contains('权限')) { return Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.no_encryption, color: Colors.orange, size: 20.sp), SizedBox(width: 8.w), Text( '缺少必要权限', style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.w600, color: Colors.orange, ), ), ], ), SizedBox(height: 8.h), Text( controller.errorMessage, style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.white70 : Colors.black54, ), textAlign: TextAlign.center, ), SizedBox(height: 16.h), ElevatedButton( onPressed: () => openAppSettings(), style: ElevatedButton.styleFrom( backgroundColor: Colors.orange, foregroundColor: Colors.white, padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.r), ), ), child: const Text('打开设置'), ), ], ); } // 其他错误 return Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.error, color: Colors.red, size: 20.sp), SizedBox(width: 8.w), Text( status.isEmpty ? '未找到设备' : status, style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.w600, color: Colors.red, ), ), ], ), SizedBox(height: 8.h), Text( controller.errorMessage.isEmpty ? '请确保耳机已开机并在附近' : controller.errorMessage, style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.white70 : Colors.black54, ), textAlign: TextAlign.center, ), ], ); } // 默认状态(正在搜索/初始化) return Column( children: [ Text( status, style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), SizedBox(height: 8.h), Text( '请打开耳机充电盒,将耳机放入您的耳朵', style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.white70 : Colors.black54, ), ), ], ); }); } // 底部按钮 Widget _buildBottomButtons(bool isDarkMode) { return Column( children: [ SizedBox( width: double.infinity, child: ElevatedButton( onPressed: controller.refreshSearch, style: ElevatedButton.styleFrom( backgroundColor: isDarkMode ? Color(0xFF1A1A1A) : Colors.grey.withOpacity(0.1), foregroundColor: isDarkMode ? Colors.white : Colors.black, padding: EdgeInsets.symmetric(vertical: 16.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16.r), ), elevation: 0, ), child: Text( '刷新搜索', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w500, ), ), ), ), SizedBox(height: 12.h), SizedBox( width: double.infinity, child: TextButton( onPressed: controller.skipConnecting, style: TextButton.styleFrom( foregroundColor: const Color(0xFF0066CC), padding: EdgeInsets.symmetric(vertical: 12.h), ), child: Text( '稍后再说', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w500, ), ), ), ), ], ); } }