Browse Source

feat(悬浮窗): 添加点击悬浮窗返回翻译页面功能

实现悬浮窗语言区域点击返回翻译页面功能,并记录上次翻译模式
- 在Android平台下记录当前翻译模式
- 点击悬浮窗语言区域时返回翻译页面并恢复上次模式
- 添加模式存储和读取功能
weicu
lxm 9 months ago
parent
commit
14cf6ccf8b
  1. 40
      lib/core/services/floating_window_manager.dart
  2. 6
      lib/modules/translation/controllers/translation_controller.dart
  3. 21
      local_plugins/native_plugin/android/src/main/kotlin/com/example/native_plugin/FloatingWindowService.kt

40
lib/core/services/floating_window_manager.dart

@ -2,8 +2,11 @@ import 'dart:async';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:floating_ui_plugin/native_plugin.dart'; import 'package:floating_ui_plugin/native_plugin.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import '../utils/logger.dart'; import '../utils/logger.dart';
import '../utils/overlay_permission_util.dart'; import '../utils/overlay_permission_util.dart';
import '../../routes/app_routes.dart';
import '../../modules/translation/controllers/translation_controller.dart';
/// 悬浮窗状态 /// 悬浮窗状态
enum FloatingWindowState { enum FloatingWindowState {
@ -48,6 +51,9 @@ class FloatingWindowManager extends GetxController {
static MethodChannel get _channel => TranslationFloatingWindowApi.channel; static MethodChannel get _channel => TranslationFloatingWindowApi.channel;
final TranslationFloatingWindowApi _api = TranslationFloatingWindowApi(); final TranslationFloatingWindowApi _api = TranslationFloatingWindowApi();
static const String _lastTranslationModeKey =
'floating_window_last_translation_mode';
final GetStorage _storage = GetStorage();
final _isEnabled = false.obs; final _isEnabled = false.obs;
final _currentState = FloatingWindowState.hidden.obs; final _currentState = FloatingWindowState.hidden.obs;
@ -79,7 +85,7 @@ class FloatingWindowManager extends GetxController {
break; break;
case 'onFloatingWindowClicked': case 'onFloatingWindowClicked':
// 悬浮窗被点击,可以执行相应操作(如返回主应用) // 悬浮窗被点击,可以执行相应操作(如返回主应用)
_handleFloatingWindowClick(); await _handleFloatingWindowClick();
break; break;
} }
}); });
@ -194,9 +200,33 @@ class FloatingWindowManager extends GetxController {
} }
/// 处理悬浮窗点击事件 /// 处理悬浮窗点击事件
void _handleFloatingWindowClick() { Future<void> _handleFloatingWindowClick() async {
// 这里可以实现点击悬浮窗后的操作,比如返回主应用 final String mode = getLastTranslationMode();
Logger.info('悬浮窗被点击'); Logger.info('悬浮窗语言区域被点击,返回翻译页面: $mode');
// 可以发送事件给其他组件处理
if (Get.isRegistered<TranslationController>()) {
final controller = Get.find<TranslationController>();
if (controller.currentMode.value != mode) {
await controller.changeTranslationMode(mode);
}
}
if (Get.currentRoute != Routes.translation) {
Get.toNamed(Routes.translation, arguments: {'translationId': mode});
}
}
void setLastTranslationMode(String mode) {
_storage.write(_lastTranslationModeKey, _normalizeTranslationMode(mode));
}
String getLastTranslationMode() {
final String? mode = _storage.read<String>(_lastTranslationModeKey);
return _normalizeTranslationMode(mode);
}
String _normalizeTranslationMode(String? mode) {
if (mode == 'audioVideo' || mode == 'call') return mode!;
return 'call';
} }
} }

6
lib/modules/translation/controllers/translation_controller.dart

@ -315,6 +315,12 @@ class TranslationController extends GetxController with WidgetsBindingObserver {
loadTranslationHistory(); loadTranslationHistory();
//stopAll(); //stopAll();
if (Platform.isAndroid && (mode == 'call' || mode == 'audioVideo')) {
try {
_floatingWindowManager.setLastTranslationMode(mode);
} catch (_) {}
}
// 检查悬浮窗支持情况 // 检查悬浮窗支持情况
if (isFloatingWindowEnabled.value && !_isFloatingWindowSupportedMode()) { if (isFloatingWindowEnabled.value && !_isFloatingWindowSupportedMode()) {
// 当前模式不支持悬浮窗,自动禁用 // 当前模式不支持悬浮窗,自动禁用

21
local_plugins/native_plugin/android/src/main/kotlin/com/example/native_plugin/FloatingWindowService.kt

@ -459,6 +459,11 @@ class FloatingWindowService : Service() {
stopSelf() stopSelf()
notifyClosed() notifyClosed()
} }
languageInfoView?.setOnClickListener {
bringAppToFront()
notifyClicked()
}
} }
private fun setupDragListener() { private fun setupDragListener() {
@ -492,6 +497,9 @@ class FloatingWindowService : Service() {
if (!isMinimized && isTouchingView(resizeHandleView, event.rawX, event.rawY)) { if (!isMinimized && isTouchingView(resizeHandleView, event.rawX, event.rawY)) {
return false return false
} }
if (!isMinimized && isTouchingView(languageInfoView, event.rawX, event.rawY)) {
return false
}
dragging = false dragging = false
scaling = false scaling = false
@ -684,6 +692,19 @@ class FloatingWindowService : Service() {
channel.invokeMethod("onFloatingWindowClicked", null) channel.invokeMethod("onFloatingWindowClicked", null)
} }
private fun bringAppToFront() {
try {
val launchIntent = packageManager.getLaunchIntentForPackage(packageName) ?: return
launchIntent.addFlags(
Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_SINGLE_TOP or
Intent.FLAG_ACTIVITY_CLEAR_TOP
)
startActivity(launchIntent)
} catch (_: Exception) {
}
}
private fun dp(value: Int): Int { private fun dp(value: Int): Int {
return (value * resources.displayMetrics.density).toInt() return (value * resources.displayMetrics.density).toInt()
} }

Loading…
Cancel
Save