import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import '../../controllers/translation_controller.dart'; import '../dialogs/translation_mode_selector.dart'; /// 可拖拽悬浮按钮组件 class DraggableFloatingButton extends StatelessWidget { final bool isDarkMode; final TranslationController controller; const DraggableFloatingButton({ Key? key, required this.isDarkMode, required this.controller, }) : super(key: key); @override Widget build(BuildContext context) { return Obx(() => Positioned( right: controller.floatingButtonPosition.value.dx, // 使用保存的位置 bottom: controller.floatingButtonPosition.value.dy, // 使用保存的位置 child: Draggable( feedback: Material( color: Colors.transparent, child: Container( width: 56.w, height: 56.w, decoration: BoxDecoration( color: (isDarkMode ? Colors.grey[700] : Colors.blue) ?.withOpacity(0.8), shape: BoxShape.circle, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.3), blurRadius: 8, offset: const Offset(0, 4), ), ], ), child: Icon( Icons.translate, color: Colors.white, size: 24.sp, ), ), ), childWhenDragging: Container( width: 56.w, height: 56.w, decoration: BoxDecoration( color: (isDarkMode ? Colors.grey[700] : Colors.blue) ?.withOpacity(0.3), shape: BoxShape.circle, ), ), onDragEnd: (details) { _handleDragEnd(context, details); }, child: GestureDetector( onTap: () => _showTranslationModeSelector(isDarkMode), child: Container( width: 56.w, height: 56.w, decoration: BoxDecoration( color: isDarkMode ? Colors.grey[700] : Colors.blue, shape: BoxShape.circle, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.2), blurRadius: 6, offset: const Offset(0, 3), ), ], ), child: Icon( Icons.translate, color: Colors.white, size: 24.sp, ), ), ), ), )); } /// 处理拖拽结束事件 void _handleDragEnd(BuildContext context, DraggableDetails details) { final screenSize = MediaQuery.of(context).size; final appBarHeight = Scaffold.of(context).appBarMaxHeight ?? kToolbarHeight; final statusBarHeight = MediaQuery.of(context).padding.top; final safeAreaTop = statusBarHeight + appBarHeight; // 计算新位置(相对于屏幕右下角) final newRight = screenSize.width - details.offset.dx - 56.w; final newBottom = screenSize.height - details.offset.dy - 56.w; // 边界检查,确保按钮不会超出屏幕或被AppBar遮盖 final clampedRight = newRight.clamp(0.0, screenSize.width - 56.w); final clampedBottom = newBottom.clamp( 0.0, // 底部边界 screenSize.height - safeAreaTop - 56.w, // 顶部边界(避免被AppBar遮盖) ); // 保存新位置 controller.saveFloatingButtonPosition(Offset(clampedRight, clampedBottom)); } /// 显示翻译模式选择器 void _showTranslationModeSelector(bool isDarkMode) { // 直接调用模式选择器,它会自动从悬浮按钮位置展开 TranslationModeSelector.show(isDarkMode); } }