Browse Source

add

newdev_shunjiawei
wolfplus 1 year ago
parent
commit
95d663a7a7
  1. 1
      lib/data/services/bluetooth_manager.dart
  2. 1
      lib/modules/home/controllers/home_controller.dart
  3. 7
      lib/modules/home/views/home_view.dart
  4. 1022
      lib/modules/pairing/controllers/pairing_controller.dart
  5. 184
      lib/modules/pairing/views/pairing_view.dart
  6. 253
      lib/modules/pairing/views/pairing_view_new.dart

1
lib/data/services/bluetooth_manager.dart

@ -13,6 +13,7 @@ class BluetoothManager extends GetxService {
// 蓝牙状态
final _bluetoothState = 'unknown'.obs;
String get bluetoothState => _bluetoothState.value;
RxString get bluetoothStateRx => _bluetoothState;
// 当前经典蓝牙设备
final Rx<BluetoothDevice?> currentDeviceRx = Rx<BluetoothDevice?>(null);

1
lib/modules/home/controllers/home_controller.dart

@ -24,6 +24,7 @@ class HomeController extends GetxController {
// Getter方法
bool get isFullyConnected => _isFullyConnected.value;
RxBool get isFullyConnectedRx => _isFullyConnected; // 响应式getter供UI使用
BluetoothDevice? get currentDevice => _bluetoothManager.currentDevice;
Rx<DeviceInfo?> get deviceInfo => _bleManager.deviceInfo;

7
lib/modules/home/views/home_view.dart

@ -225,8 +225,8 @@ class HomeView extends GetView<HomeController> {
SizedBox(height: 12.h),
Obx(() {
// 移除连接失败和连接中的状态判断,直接根据是否完全连接来判断
return controller.isFullyConnected
// 使用响应式访问确保UI更新
return controller.isFullyConnectedRx.value
? _buildConnectedDeviceInfo(isDarkMode) //已连接设备信息
: _buildDisconnectedInfo(isDarkMode); //未连接提示
}),
@ -234,7 +234,8 @@ class HomeView extends GetView<HomeController> {
// 连接按钮(仅在未连接时显示)
SizedBox(height: 12.h),
Obx(() {
if (!controller.isFullyConnected) {
// 使用响应式访问确保UI更新
if (!controller.isFullyConnectedRx.value) {
return _buildConnectButton();
} else {
return const SizedBox();

1022
lib/modules/pairing/controllers/pairing_controller.dart

File diff suppressed because it is too large

184
lib/modules/pairing/views/pairing_view.dart

@ -2,8 +2,6 @@ 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';
class PairingView extends GetView<PairingController> {
const PairingView({Key? key}) : super(key: key);
@ -97,28 +95,25 @@ class PairingView extends GetView<PairingController> {
// 设备动画 - 根据状态显示不同的动画效果
Widget _buildDeviceAnimation(bool isDarkMode) {
return Obx(() {
final state = controller.state;
final state = controller.currentState;
final isLoading = controller.isLoading.value;
final isReadyToStart = controller.isReadyToStart.value;
final isManualMode = controller.isManualMode.value;
// 根据状态决定动画颜色
Color primaryColor = Color(0xFF0066CC);
Color secondaryColor = Color(0xFF5E5CE6);
// 错误状态使用红色
if (state.name.startsWith('exit')) {
if (state == PairingState.error) {
primaryColor = Colors.red;
secondaryColor = Colors.redAccent;
}
// 成功状态使用绿色
else if (state == PairingState.paired) {
else if (state == PairingState.completed) {
primaryColor = Colors.green;
secondaryColor = Colors.greenAccent;
}
// 手动模式待机状态的特殊处理
if (isManualMode && isReadyToStart) {
// 待机状态的特殊处理
if (state == PairingState.idle || state == PairingState.waitingClassic) {
return Container(
width: 240.w,
height: 240.w,
@ -237,19 +232,20 @@ class PairingView extends GetView<PairingController> {
// 根据状态获取图标
IconData _getIconForState(PairingState state) {
switch (state) {
case PairingState.paired:
case PairingState.completed:
return Icons.check_circle;
case PairingState.exitNoPermission:
case PairingState.exitBtOff:
return Icons.bluetooth_disabled;
case PairingState.exitNoClassic:
case PairingState.exitNotMatch:
return Icons.headphones_outlined;
case PairingState.exitPairFailed:
case PairingState.exitTimeout:
case PairingState.exitIllegal:
case PairingState.exitBound:
return Icons.error_outline;
case PairingState.error:
final errorType = controller.errorType;
switch (errorType) {
case ErrorType.bluetoothOff:
case ErrorType.noPermission:
return Icons.bluetooth_disabled;
case ErrorType.noClassicDevice:
case ErrorType.deviceNotMatch:
return Icons.headphones_outlined;
default:
return Icons.error_outline;
}
default:
return Icons.headphones;
}
@ -258,8 +254,8 @@ class PairingView extends GetView<PairingController> {
// 状态信息
Widget _buildStatusInfo(bool isDarkMode) {
return Obx(() {
final status = controller.statusDescription.value;
final state = controller.state;
final status = controller.statusText.value;
final state = controller.currentState;
final device = controller.currentDevice;
return Column(
@ -289,10 +285,9 @@ class PairingView extends GetView<PairingController> {
// 当前连接设备(有设备时才显示)
if (device != null &&
(state == PairingState.classicOk ||
state == PairingState.serverVerify ||
state == PairingState.pairing ||
state == PairingState.paired)) ...[
(state == PairingState.verifying ||
state == PairingState.waitingBle ||
state == PairingState.completed)) ...[
SizedBox(height: 24.h),
_buildConnectedDevice(device, isDarkMode),
],
@ -303,37 +298,39 @@ class PairingView extends GetView<PairingController> {
// 根据状态获取副标题
String _getSubtitleForState(PairingState state) {
if (controller.isManualMode.value && controller.isReadyToStart.value) {
return '点击下方按钮开始配对您的DeapSound设备';
}
switch (state) {
case PairingState.init:
case PairingState.btReady:
return controller.isManualMode.value ? '准备开始配对' : '正在准备配对环境...';
case PairingState.classicOk:
case PairingState.idle:
return '准备开始配对';
case PairingState.checking:
return '正在准备配对环境...';
case PairingState.waitingClassic:
return '请先通过系统蓝牙连接DeapSound设备';
case PairingState.serverVerify:
case PairingState.pairing:
case PairingState.verifying:
return '正在验证设备...';
case PairingState.waitingBle:
return '请稍候,正在完成配对...';
case PairingState.paired:
case PairingState.completed:
return '配对成功!即将跳转到主页...';
case PairingState.exitNoPermission:
return '需要蓝牙权限才能继续';
case PairingState.exitBtOff:
return '请开启蓝牙后重试';
case PairingState.exitNoClassic:
return '请先通过系统蓝牙连接DeapSound设备';
case PairingState.exitNotMatch:
return '请确保连接的是DeapSound设备';
case PairingState.exitTimeout:
return '扫描超时,请确保设备在附近';
case PairingState.exitPairFailed:
return '配对失败,请重试';
case PairingState.exitBound:
return '该设备已被其他账号绑定';
case PairingState.exitIllegal:
return '设备验证失败,请检查设备是否正常';
case PairingState.error:
final errorType = controller.errorType;
switch (errorType) {
case ErrorType.bluetoothOff:
return '请开启蓝牙后重试';
case ErrorType.noPermission:
return '需要蓝牙权限才能继续';
case ErrorType.noClassicDevice:
return '请先通过系统蓝牙连接DeapSound设备';
case ErrorType.deviceNotMatch:
return '请确保连接的是DeapSound设备';
case ErrorType.deviceBound:
return '该设备已被其他账号绑定';
case ErrorType.bleTimeout:
return '扫描超时,请确保设备在附近';
case ErrorType.networkError:
return '网络错误,请检查网络连接';
default:
return '配对失败,请重试';
}
default:
return '';
}
@ -411,23 +408,32 @@ class PairingView extends GetView<PairingController> {
);
}
// 获取连接按钮图标
IconData _getConnectButtonIcon() {
final buttonText = controller.connectButtonText.value;
if (buttonText.contains('蓝牙')) {
return Icons.bluetooth;
} else if (buttonText.contains('设置')) {
return Icons.settings;
}
return Icons.bluetooth_searching;
}
// 操作按钮
Widget _buildActionButtons(bool isDarkMode) {
return Obx(() {
final showActionButton = controller.showActionButton;
final canSkip = controller.canSkip;
final actionButtonText = controller.actionButtonText.value;
final isReadyToStart = controller.isReadyToStart.value;
final isManualMode = controller.isManualMode.value;
final showConnectButton = controller.showConnectButton.value;
final showRetryButton = controller.showRetryButton.value;
final showSkipButton = controller.showSkipButton.value;
return Container(
width: double.infinity,
child: Column(
children: [
// 手动模式:显示开始配对按钮
if (isManualMode && isReadyToStart)
// 显示连接按钮
if (showConnectButton)
ElevatedButton(
onPressed: () => controller.startManualPairing(),
onPressed: () => controller.onConnectTap(),
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFF0066CC),
foregroundColor: Colors.white,
@ -441,10 +447,10 @@ class PairingView extends GetView<PairingController> {
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.bluetooth_searching, size: 20.w),
Icon(_getConnectButtonIcon(), size: 20.w),
SizedBox(width: 8.w),
Text(
'开始配对设备',
controller.connectButtonText.value,
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
@ -454,13 +460,12 @@ class PairingView extends GetView<PairingController> {
),
),
// 原有的状态按钮(错误处理等)
if (showActionButton && !isManualMode)
// 显示重试按钮
if (showRetryButton)
ElevatedButton(
onPressed: () => controller.handleActionButtonTap(),
onPressed: () => controller.onRetryTap(),
style: ElevatedButton.styleFrom(
backgroundColor:
_getButtonColor(controller.state, isDarkMode),
backgroundColor: Colors.red,
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(vertical: 16.h),
shape: RoundedRectangleBorder(
@ -470,7 +475,7 @@ class PairingView extends GetView<PairingController> {
minimumSize: Size(double.infinity, 56.h),
),
child: Text(
actionButtonText,
controller.retryButtonText.value,
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
@ -478,11 +483,11 @@ class PairingView extends GetView<PairingController> {
),
),
// 跳过按钮和重置按钮
if (canSkip) ...[
// 跳过按钮
if (showSkipButton) ...[
SizedBox(height: 12.h),
TextButton(
onPressed: () => controller.skipPairing(),
onPressed: () => controller.onSkipTap(),
style: TextButton.styleFrom(
foregroundColor: Color(0xFF0066CC),
padding: EdgeInsets.symmetric(vertical: 12.h),
@ -498,41 +503,10 @@ class PairingView extends GetView<PairingController> {
),
],
// 添加重置按钮(在错误状态下)
if (!isManualMode &&
!controller.isLoading.value &&
controller.state.name.startsWith('exit')) ...[
SizedBox(height: 8.h),
TextButton(
onPressed: () => controller.resetToManualMode(),
style: TextButton.styleFrom(
foregroundColor: Colors.grey,
padding: EdgeInsets.symmetric(vertical: 8.h),
),
child: Text(
'重新配对',
style: TextStyle(fontSize: 14.sp),
),
),
],
],
),
);
});
}
// 根据状态获取按钮颜色
Color _getButtonColor(PairingState state, bool isDarkMode) {
switch (state) {
case PairingState.exitNoPermission:
case PairingState.exitBtOff:
return isDarkMode ? Colors.grey[800]! : Colors.grey[600]!;
case PairingState.exitPairFailed:
case PairingState.exitBound:
case PairingState.exitIllegal:
return Colors.red;
default:
return Color(0xFF0066CC);
}
}
}

253
lib/modules/pairing/views/pairing_view_new.dart

@ -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…
Cancel
Save