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:floating_ui_plugin/native_plugin.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import '../utils/logger.dart';
import '../utils/overlay_permission_util.dart';
import '../../routes/app_routes.dart';
import '../../modules/translation/controllers/translation_controller.dart';
/// 悬浮窗状态
enum FloatingWindowState {
@ -48,6 +51,9 @@ class FloatingWindowManager extends GetxController {
static MethodChannel get _channel => TranslationFloatingWindowApi.channel;
final TranslationFloatingWindowApi _api = TranslationFloatingWindowApi();
static const String _lastTranslationModeKey =
'floating_window_last_translation_mode';
final GetStorage _storage = GetStorage();
final _isEnabled = false.obs;
final _currentState = FloatingWindowState.hidden.obs;
@ -79,7 +85,7 @@ class FloatingWindowManager extends GetxController {
break;
case 'onFloatingWindowClicked':
// 悬浮窗被点击,可以执行相应操作(如返回主应用)
_handleFloatingWindowClick();
await _handleFloatingWindowClick();
break;
}
});
@ -194,9 +200,33 @@ class FloatingWindowManager extends GetxController {
}
/// 处理悬浮窗点击事件
void _handleFloatingWindowClick() {
// 这里可以实现点击悬浮窗后的操作,比如返回主应用
Logger.info('悬浮窗被点击');
// 可以发送事件给其他组件处理
Future<void> _handleFloatingWindowClick() async {
final String mode = getLastTranslationMode();
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();
//stopAll();
if (Platform.isAndroid && (mode == 'call' || mode == 'audioVideo')) {
try {
_floatingWindowManager.setLastTranslationMode(mode);
} catch (_) {}
}
// 检查悬浮窗支持情况
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()
notifyClosed()
}
languageInfoView?.setOnClickListener {
bringAppToFront()
notifyClicked()
}
}
private fun setupDragListener() {
@ -492,6 +497,9 @@ class FloatingWindowService : Service() {
if (!isMinimized && isTouchingView(resizeHandleView, event.rawX, event.rawY)) {
return false
}
if (!isMinimized && isTouchingView(languageInfoView, event.rawX, event.rawY)) {
return false
}
dragging = false
scaling = false
@ -684,6 +692,19 @@ class FloatingWindowService : Service() {
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 {
return (value * resources.displayMetrics.density).toInt()
}

Loading…
Cancel
Save