diff --git a/android/app/src/main/kotlin/com/saitong/voitrans/FloatingWindowService.kt b/android/app/src/main/kotlin/com/saitong/voitrans/FloatingWindowService.kt index 8d4f460e9..b6e861db2 100644 --- a/android/app/src/main/kotlin/com/saitong/voitrans/FloatingWindowService.kt +++ b/android/app/src/main/kotlin/com/saitong/voitrans/FloatingWindowService.kt @@ -19,6 +19,7 @@ class FloatingWindowService : Service() { private var windowManager: WindowManager? = null private var floatingView: View? = null private var isMinimized = true + private lateinit var layoutParams: WindowManager.LayoutParams private lateinit var sourceTextView: TextView private lateinit var translatedTextView: TextView @@ -73,7 +74,7 @@ class FloatingWindowService : Service() { setupClickListeners() // 设置窗口参数 - val layoutParams = WindowManager.LayoutParams().apply { + layoutParams = WindowManager.LayoutParams().apply { width = WindowManager.LayoutParams.WRAP_CONTENT height = WindowManager.LayoutParams.WRAP_CONTENT type = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -255,26 +256,12 @@ class FloatingWindowService : Service() { } private fun setupClickListeners() { - // 最小化状态点击展开 - minimizedView.setOnClickListener { - isMinimized = false - updateViewState(false) - notifyStateChange("expanded") - } - - // 展开状态点击最小化 - expandedView.setOnClickListener { - isMinimized = true - updateViewState(true) - notifyStateChange("minimized") - } - // 长按关闭 floatingView!!.setOnLongClickListener { closeFloatingWindow() true } - + // 拖拽功能 setupDragListener() } @@ -284,25 +271,40 @@ class FloatingWindowService : Service() { var initialY = 0 var initialTouchX = 0f var initialTouchY = 0f - + var dragging = false + val threshold = (4 * resources.displayMetrics.density).toInt() floatingView!!.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { - val layoutParams = floatingView!!.layoutParams as WindowManager.LayoutParams initialX = layoutParams.x initialY = layoutParams.y initialTouchX = event.rawX initialTouchY = event.rawY + dragging = false true } MotionEvent.ACTION_MOVE -> { - val layoutParams = floatingView!!.layoutParams as WindowManager.LayoutParams - layoutParams.x = initialX + (event.rawX - initialTouchX).toInt() - layoutParams.y = initialY + (event.rawY - initialTouchY).toInt() + val dx = (event.rawX - initialTouchX).toInt() + val dy = (event.rawY - initialTouchY).toInt() + if (Math.abs(dx) > threshold || Math.abs(dy) > threshold) dragging = true + val dm = resources.displayMetrics + val maxX = dm.widthPixels - (floatingView?.width ?: 0) + val maxY = dm.heightPixels - (floatingView?.height ?: 0) + layoutParams.x = (initialX + dx).coerceIn(0, maxX) + layoutParams.y = (initialY + dy).coerceIn(0, maxY) windowManager?.updateViewLayout(floatingView, layoutParams) true } - else -> false + MotionEvent.ACTION_UP -> { + if (!dragging) { + isMinimized = !isMinimized + updateViewState(isMinimized) + notifyStateChange(if (isMinimized) "minimized" else "expanded") + } + dragging = false + true + } + else -> true } } } @@ -347,11 +349,10 @@ class FloatingWindowService : Service() { val x = intent.getIntExtra(EXTRA_X, 0) val y = intent.getIntExtra(EXTRA_Y, 0) - floatingView?.let { view -> - val layoutParams = view.layoutParams as WindowManager.LayoutParams + floatingView?.let { layoutParams.x = x layoutParams.y = y - windowManager?.updateViewLayout(view, layoutParams) + windowManager?.updateViewLayout(it, layoutParams) } } diff --git a/lib/modules/eq_settings/bindings/eq_settings_binding.dart b/lib/modules/eq_settings/bindings/eq_settings_binding.dart new file mode 100644 index 000000000..1f2884bd2 --- /dev/null +++ b/lib/modules/eq_settings/bindings/eq_settings_binding.dart @@ -0,0 +1,10 @@ +import 'package:get/get.dart'; + +import '../controllers/eq_settings_controller.dart'; + +class EqSettingsBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut(() => EqSettingsController()); + } +} diff --git a/lib/modules/eq_settings/controllers/eq_settings_controller.dart b/lib/modules/eq_settings/controllers/eq_settings_controller.dart new file mode 100644 index 000000000..ef5daae05 --- /dev/null +++ b/lib/modules/eq_settings/controllers/eq_settings_controller.dart @@ -0,0 +1,3 @@ +import 'package:get/get.dart'; + +class EqSettingsController extends GetxController {} diff --git a/lib/modules/eq_settings/views/eq_settings_view.dart b/lib/modules/eq_settings/views/eq_settings_view.dart new file mode 100644 index 000000000..32c26179f --- /dev/null +++ b/lib/modules/eq_settings/views/eq_settings_view.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../controllers/eq_settings_controller.dart'; + +class EqSettingsView extends GetView { + const EqSettingsView({super.key}); + + @override + Widget build(BuildContext context) { + return const Placeholder(); + } +} diff --git a/lib/routes/app_pages.dart b/lib/routes/app_pages.dart index 8d9b2ee2b..f6ba20dfa 100644 --- a/lib/routes/app_pages.dart +++ b/lib/routes/app_pages.dart @@ -1,5 +1,7 @@ import 'package:get/get.dart'; import 'package:qq_music/qq_music.dart'; +import '../modules/eq_settings/bindings/eq_settings_binding.dart'; +import '../modules/eq_settings/views/eq_settings_view.dart'; import '/modules/qqmusic/bindings/qqmusic_playlist_binding.dart'; import '/modules/qqmusic/views/qqmusic_playlist_view.dart'; @@ -324,5 +326,12 @@ abstract class AppPages { transition: Transition.rightToLeft, transitionDuration: Duration(milliseconds: 250), ), + GetPage( + name: Routes.eqSettings, + page: () => const EqSettingsView(), + binding: EqSettingsBinding(), + transition: Transition.rightToLeft, + transitionDuration: Duration(milliseconds: 250), + ), ]; } diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index b513e0369..fd9440940 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -19,6 +19,7 @@ abstract class Routes { static const settings = '/settings'; // 系统设置 static const permissions = '/permissions'; // 权限管理 static const recording = '/recording'; // 录音功能 + static const eqSettings = '/eq_settings'; // 设备设置 // 会议相关 static const meeting = '/meeting';